关于@Transaction同类调用不生效原因详解

发布时间 2023-10-11 22:02:12作者: Great-R

首先简单介绍一下事务注解方式的实现原理:
在项目启动类中配置了@EnableTransactionManagement注解,此注解会拦截所有bean的创建,然后查看这个bean是否存在@Transaction注解(类、接口、方法上都可以),如果存在这个注解,spring会通过aop的方式去创建这个bean的代理类,代理类中会增加一个拦截器,拦截器会拦截配置事务的public方法执行,在方法执行开始前开启事务,在方法执行结束之后提交或者回滚事务。
示例:

@Service
public class TestTransaction {

    @Transactional
    void a() {

    }

    void b() {
        a();
    }
}

会生成一个类似于以下的代理类

public class Proxy$TestTransaction {
    
    void a() {
		startTransaction();//方法开启之前的开启事务方法
        TestTransaction.a();//类具体的执行方法
        //提交或回滚事务
    }

    void b() {
        TestTransaction.b();//类具体的执行方法
    }
}

那么问题来了,同类下方法A配置了注解,方法B没有,方法B中调用的方法A,事务会不生效。
通过以上代码其实已经很容易理解了,外部类在调用了方法B时,代理类方法B是直接执行了类的具体方法(具体方法B只是调用的A方法),并没有事务的开启等,所以事务才会不生效。
总结
同类下事务不生效的主要原因就是aop代理类生成具体未注解@Transactional方法时,只是生成了类的具体方法,并没有在方法前后做增强方法的操作。同理异步等等注解同类下不生效的原因大致都是如此。
参考1:https://blog.csdn.net/NoviceZ/article/details/128284424
参考2:https://blog.csdn.net/qq_43585377/article/details/127573863