基于JDK动态代理和CGLIB动态代理的实现Spring注解管理事务(@Trasactional)到底有什么区别

来源:互联网 发布:macbook卸载软件 编辑:程序博客网 时间:2024/05/16 00:38

基于JDK动态代理:

<tx:annotation-driven transaction-manager="txManager"/> 

该配置方式默认就是JDK动态代理方式

 

运行单元测试,核心日志如下: 




到此我们可以看到事务起作用了,也就是说即使把@Transactional放到接口上 基于JDK动态代理也是可以工作的。

基于CGLIB类代理:

<tx:annotation-driven transaction-manager="txManager" proxy-target-class="true"/>

该配置方式是基于CGLIB类代理

 

启动测试会报错,No Session found for current thread,说明事务没有起作用



如果将注解放在具体类上或具体类的实现方法上才会起作用。
package cn.javass.common.service.impl;  public abstract class BaseServiceImpl implements BaseService {      @Transactional()     @Override      public int countAll() {          return baseDao.countAll();      }  }

运行测试类,将发现成功了,因为我们的UserService继承该方法,但如果UserService覆盖该方法,如下所示,也将无法织入事务(报错):
package cn.javass.demo.service.impl;  public class UserServiceImpl extends BaseServiceImpl implements UserService {      //没有@Transactional      @Override       public int countAll() {          return baseDao.countAll();      }  }  


基于aspectj的
<tx:annotation-driven transaction-manager="txManager" mode="aspectj" proxy-target-class="true"/>  
在此就不演示了,我们主要分析基于JDK动态代理和CGLIB类代理两种的区别。

结论:

基于JDK动态代理 ,可以将@Transactional放置在接口具体类或者具体类的实现方法上。

基于CGLIB类代理,只能将@Transactional放置在具体类或者具体类的实现方法上。

 

因此 在实际开发时全部将@Transactional放到具体类上,而不是接口上。

0 0