Spring Bean 假设有如下类
public class Service implement IService{
@Transactional(readOnly = false, propagation=Propagation.REQUIRED)
public void methodA(){
//.....
methodB()
//......
}
@Transactional(readOnly = false, propagation=Propagation.REQUIRES_NEW)
public void methodB{
//......
}
}
public class ServiceFacade{
@Autowired
private Iservice service;
public void method(){
//...
service.methodA();
//...
}
}
1.问调用 ServiceFacade 的 method() 方法,请问 methodA 和 methodB 事务是怎么样的?
2.在同一个事务还是两个事务,methodA 事务生效还是 methodB 事务生效,还是都生效?
答案是 methodA 的事务生效,methodB 被嵌入到 methodA 中变成一个事务。
为什么会这样呢?methodB 不是声明了 Propagation.REQUIRES_NEW 吗?
答案得从 Spring 的事务实现说起,Spring 的事务是通过 AOP 动态代理实现的。
为 Bean 生成代理。因为 methodB 在 Service 内部被调用,此时执行的并不是代理 Bean 的 methodB,所以methodB 上面的事务声明失效
Facade 调用 Service 的 methodA 方法的时候,实际上执行的是 serviceProxy.methodA ,所以 method 被Spring 事务接管,事务声明生效。
解决的办法是,methodB 放在另外的 Bean中被methodA 调用或者 Facade 调用 service.methodA() ,然后调用 service.methodB
总结:Spring 的事务是基于 AOP 动态代理实现的。默认情况下,在同一个类中调用不同的方法,上面的事务声明是无效的。