Spring同一个class类中的@Transactional事务调用另一个事务不生效的解决方案
在Java的Impl实现层中,经常会遇到如下的方法之间调用
public class xxxServiceImpl implements xxxService {
@Override
@Transactional
public void A() {
……
B();
}
@Transactional
private void B() {
……
}
}
事务方法A() 中调用事务方法B() ,在执行代码的时候会发现,B方法出现异常后,事务不会回滚。
Spring采用动态代理(AOP)实现对Bean的管理和切片,它为我们的每个class生成一个代理对象。只有在代理对象之间进行调用时,可以触发切面逻辑。而在同一个class类中,方法A调用方法B,调用的是原对象的方法,而不是代理对象。所以直接调用当前类中的事务方法是不会生效的。
解决方案:
方法一:调用新事务方法时,将当前事务挂起,重新开启另一个新的事务来执行语句
1、启动类:添加注解@EnableAspectJAutoProxy(exposeProxy = true)
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@SpringBootApplication
@EnableAspectJAutoProxy(exposeProxy = true)
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
2、实现类:通过AopContext.currentProxy())代理的方式调用
public class xxxServiceImpl implements xxxService {
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void A() {
……
((xxxServiceImpl) AopContext.currentProxy()).B();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void B() {
……
}
方法二:注入类自己,调用事务方法
public class xxxServiceImpl implements xxxService {
@Autowired
private xxxServiceImpl serviceImpl;
@Override
@Transactional(propagation = Propagation.REQUIRED)
public void A() {
……
serviceImpl.B();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void B() {
……
}