Spring 事务的一个误区

2014/12/09 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();
   //...
  }

}

1.问调用 ServiceFacademethod() 方法,请问 methodAmethodB 事务是怎么样的?

2.在同一个事务还是两个事务,methodA 事务生效还是 methodB 事务生效,还是都生效?

答案是 methodA 的事务生效,methodB 被嵌入到 methodA 中变成一个事务。

为什么会这样呢?methodB 不是声明了 Propagation.REQUIRES_NEW 吗?

答案得从 Spring 的事务实现说起,Spring 的事务是通过 AOP 动态代理实现的。

Bean 生成代理。因为 methodBService 内部被调用,此时执行的并不是代理 BeanmethodB,所以methodB 上面的事务声明失效

Facade 调用 ServicemethodA 方法的时候,实际上执行的是 serviceProxy.methodA ,所以 methodSpring 事务接管,事务声明生效。

解决的办法是,methodB 放在另外的 Bean中被methodA 调用或者 Facade 调用 service.methodA() ,然后调用 service.methodB

总结:Spring 的事务是基于 AOP 动态代理实现的。默认情况下,在同一个类中调用不同的方法,上面的事务声明是无效的。

Search

    Post Directory