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() {
        ……
    }