首页 > 代码库 > Spring事务使用的一个误区

Spring事务使用的一个误区

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

}

}


}
问调用ServiceFacade的method()方法,请问methodA和methodB事务是怎么样的?

在同一个事务还是两个事务,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动态代理实现的。默认情况下,在同一个类中调用不同的方法,上面的事务声明是无效的。


以上语言表达可能不够准确,但是大概是这个意思。如果您有更好的表述,请告诉我,谢谢。

Spring事务使用的一个误区