简体   繁体   English

使 Spring 3 MVC 控制器方法成为事务性的

[英]Making Spring 3 MVC controller method Transactional

I am using Spring 3.1 and have my DAO and service layer(transactional) written.我正在使用 Spring 3.1 并编写了我的 DAO 和服务层(事务)。

However in a special case to avoid a lazy init exception I have to make a spring mvc request handler method @transactional.但是在特殊情况下,为了避免延迟初始化异常,我必须创建一个 spring mvc 请求处理程序方法@transactional。 But It is failing to attach transaction to that method.但是它无法将事务附加到该方法。 Method name is ModelAndView home(HttpServletRequest request, HttpServletResponse response).方法名称是 ModelAndView home(HttpServletRequest 请求,HttpServletResponse 响应)。 http://forum.springsource.org/showthread.php?46814-Transaction-in-MVC-Controller From this link it seems it is not possible to attach transaction (by default ) to mvc methods. http://forum.springsource.org/showthread.php?46814-Transaction-in-MVC-Controller从这个链接看来不可能将事务(默认情况下)附加到 mvc 方法。 Solution suggested in that link seems to be for Spring 2.5 (overriding handleRequest ).该链接中建议的解决方案似乎适用于 Spring 2.5(覆盖 handleRequest )。 Any help will be reallyappreciated.任何帮助将不胜感激。 Thanks谢谢

@Controller
public class AuthenticationController { 
@Autowired
CategoryService categoryService;    
@Autowired
BrandService brandService;
@Autowired
ItemService itemService;

@RequestMapping(value="/login.html",method=RequestMethod.GET)
ModelAndView login(){       
    return new ModelAndView("login.jsp");       
}   
@RequestMapping(value="/home.html",method=RequestMethod.GET)
@Transactional
ModelAndView home(HttpServletRequest request, HttpServletResponse response){
    List<Category> categories = categoryService.readAll();
    request.setAttribute("categories", categories);     
    List<Brand> brands = brandService.readAll();
    request.setAttribute("brands", brands);     
    List<Item> items = itemService.readAll();
    request.setAttribute("items", items);
    Set<Image> images = items.get(0).getImages();
    for(Image i : images ) {
        System.out.println(i.getUrl());
    }
    return new ModelAndView("home.jsp");    
}

You'll need to implement an interface so that Spring has something it can use as a Proxy interface:您需要实现一个接口,以便 Spring 可以将其用作 Proxy 接口:

@Controller
public interface AuthenticationController {
  ModelAndView home(HttpServletRequest request, HttpServletResponse response);
}

@Controller
public class AuthenticationControllerImpl implements AuthenticationController {

@RequestMapping(value="/home.html",method=RequestMethod.GET)
@Transactional
@Override
ModelAndView home(HttpServletRequest request, HttpServletResponse response){
.....
}
}

Spring will implement the transactional logic using JDK dynamic proxies, these rely on proxied classes implementing suitable interfaces. Spring 将使用 JDK 动态代理实现事务逻辑,这些依赖于实现合适接口的代理类。 It's also possible to use CGLib proxies which don't require interfaces.也可以使用不需要接口的 CGLib 代理。

There is a nice article about this link关于此链接有一篇不错的文章

I'm not sure this applies to your case but if you are using separate DI contexts you should also consider how Spring weaves aspects.我不确定这是否适用于您的情况,但如果您使用单独的 DI 上下文,您还应该考虑 Spring 如何编织方面。

Spring will only apply @Transactional semantics to beans in the same DI context where @EnableTransactionManagement or <tx:annotation-driven/> is used. Spring 只会将@Transactional语义应用于使用@EnableTransactionManagement<tx:annotation-driven/>的相同DI 上下文中的bean。

So if you define your transaction configuration in the root context, only beans in that context are covered, which typically means only business services.因此,如果您在根上下文中定义事务配置,则只会覆盖该上下文中的 bean,这通常意味着只有业务服务。 You'll need to re-enable transaction management in any child context where you also use @Transactional .您需要在您还使用@Transactional的任何子上下文中重新启用事务管理。

Ref: Spring AOP - How to make aspects defined in a parent context work in child contexts?参考: Spring AOP - 如何使父上下文中定义的方面在子上下文中工作?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM