一、原因
外部经过spring容器调用service的方法事务才生效,service类内部方法间相互调用事务不生效,也就是传说中的自调用失效问题。主要原因是 Spring数据库事务的约定,其实现原理是AOP,而AOP的原理是动态代理,在自调用的过程中,是类自身的调用,而不是代理对象去调用,那么就不会产生AOP,这样 Spring就不能把你的代码织入到约定的流程中,于是就产生了现在看到的失败场景。
二、场景
如图,调用updateStatRecord方法的也是service中的一个方法,这种情况下updateStatRecord方法的方法是无法实现事务的,也就是说@Transactional注解失效了。
三、解决方案
1、引入自身bean
如图,这种情况要注意可能造成循环依赖,要小心一点使用
2、通过ApplicationContext引入bean
这种情况,事务也是可以生效的
3、通过AopContext获取当前类的代理类
通过AopContext获取当前类的代理类,直接通过代理类调用方法 在引导类上添加
@EnableAspectJAutoProxy(exposeProxy=true)注解
引入包
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
启动类增加注解@EnableAspectJAutoProxy(exposeProxy=true)
如图: