今天在看项目代码的时候,发现在service层,有方法调用同类中的方法,SonarLint提示有bug。
下图是我自己做测试时写的demo代码:
经过测试发现,当A方法调用同类中带有@Transactional
注解的B方法时,被@Transactional注解的B方法的事务是不起作用的。
原因
spring会扫描@Transactional
的类和方法,并通过动态代理实现启动事务的代理方法。
这个时候A方法是没有开启事务的,虽然B方法开启了事务,但是A方法调用B方法,是直接调用的,不会调用spring生成的开启事务的代理方法。
解决方法
- 将带有
@Transactional
注解的方法移到另一个类中,发起类之间的方法调用。 - 在第一个方法中也添加
@Transactional
注解。 - 使用
AopContext.currentProxy()
,该方法会返回当前类的spring代理对象。当我们强转为当前类的对象后,就可以调用本类中的其它方法。
经过测试的情况总结
前提:A方法调用B方法时,B方法有多个修改SQL
A方法没开启事务,B方法开启事务:A和B在同一类中,事务无效;A和B不在同一类中,事务生效。
A方法开启事务,B方法没开启事务:A和B在同一类中,事务生效;A和B不在同一类中,事务生效。