Spring事务方法中如何让method2非事务/新事务执行?控制器调用可行吗?
问题解答
一、让method2以非事务/新事务执行的解决方案
Spring事务基于动态代理实现,同一个类内部的方法直接调用(比如method里直接调用method2)不会触发代理的事务增强逻辑,所以你当前的配置无法生效,以下是可行方案:
1. 拆分到不同类
把method2单独抽离到另一个Service类,在原ServiceImpl中注入这个新Service,通过注入的实例调用method2:
@Service class AnotherService { // 要开启新事务就保留该注解,要非事务就去掉 @Transactional(propagation = Propagation.REQUIRES_NEW) public void method2() { // external api call } } @Service class ServiceImpl implements Service { @Autowired private AnotherService anotherService; @Override @Transactional public int method() { // some logic in transaction anotherService.method2(); // 触发事务增强逻辑 return 2; } }
2. 自注入代理对象
在ServiceImpl中注入自身的代理对象(注入接口Service而非实现类),通过代理对象调用method2:
@Service class ServiceImpl implements Service { @Autowired private Service selfProxy; @Override @Transactional public int method() { // some logic in transaction selfProxy.method2(); // 触发事务增强 return 2; } @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void method2() { // external api call } }
如果要让method2非事务执行,可将其注解改为@Transactional(propagation = Propagation.NOT_SUPPORTED)(挂起当前事务执行),或者直接去掉@Transactional注解。
3. 通过AopContext获取代理
先在配置类添加@EnableAspectJAutoProxy(exposeProxy = true)开启代理暴露,再通过AopContext获取当前代理对象调用method2:
@Service class ServiceImpl implements Service { @Override @Transactional public int method() { // some logic in transaction ((Service) AopContext.currentProxy()).method2(); return 2; } @Override @Transactional(propagation = Propagation.REQUIRES_NEW) public void method2() { // external api call } }
二、控制器中调用两个方法的可行性
完全可以在控制器中按如下方式调用:
service.method(); service.method2();
因为控制器注入的是Service的代理对象,每次调用都会触发事务切面逻辑:
- 调用
service.method()时,会按注解开启事务执行逻辑; - 调用
service.method2()时,会遵循其@Transactional配置(开启新事务或非事务执行)。
内容的提问来源于stack exchange,提问作者grap
相关产品推荐
相关产品推荐

