因为自己老是遗忘了spring的事务传播属性。究竟是在什么时候加事务呢?是不是本身service中的方法有事务的情况下去做这个传播呢?其实,自己老是混淆是不是有事务然后去传播。。
事实上,所有的service方法都是没有事务的,当spring做AOP时才加进去的。。当两个service操作的时候,就会进行事务处理的问题了。这两个service究竟以什么方式进行协作呢?是,两个Service运行时合并事务做,还是嵌套事务。。。就需要用到事务传播。。以前的误区就是,如果一个Ation 或者一个别的方法,调用两个service,应该如何处理。如
public String execute{
serviceA.methodA();
serviceB.methodB();
}
其实这里没有什么所谓的事务传播,只是分别调用两个不同的事务方法。如果A回滚了,B也一样继续执行的。
实质上它的事务处理是:
execute(){
事务1开始:
methodA();
事务1结束();
事务2开始:
methodB();
事务2结束;
}
而当在service中 如 ServiceC.methodC(){
serviceA.methodA();
serviceB.methodB();
}
因为serviceC 中的mehodC中本身就AOP了事务,如果C也是PROPAGATION_REQUIRED的话,那么就要在C中起一个事务。
而methodA()和methodB()中spring就不会重新注入事务了。
即整个流程变成了 C{
事务开始:
methodA();
methodB();
事务提交;
}
关于Spring的事务传播属性:
PROPAGATION_REQUIRED -- 支持当前事务,如果当前没有事务,就新建一个事务。这是最常见的选择。
PROPAGATION_SUPPORTS -- 支持当前事务,如果当前没有事务,就以非事务方式执行。
PROPAGATION_MANDATORY -- 支持当前事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW -- 新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED -- 以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER -- 以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED -- 如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则进行与PROPAGATION_REQUIRED类似的操作。
前六个策略类似于EJB CMT,第七个(PROPAGATION_NESTED)是Spring所提供的一个特殊变量。
它要求事务管理器或者使用JDBC 3.0 Savepoint API提供嵌套事务行为(如Spring的DataSourceTransactionManager)
所谓事务传播属性,就是有N个Service互相调用的时候,的处理方式。
如 ServiceA有methodA方法,它的事务传播属性是:PROPAGATION_REQUIRED 。ServiceB有methodB方法 。它的事务传播属性也是:PROPAGATION_REQUIRED
(1)当methodA()中调用serviceB.methodB()时,public methodA(){serviceB.methodB();} 当methodA执行时,根据传播属性:PROPAGATION_REQUIRED:如果当前没有事务,就新建一个事务。
(2)当前methodA()没有事务。所以spring给它新建了一个事务。
(3)到serviceB.methodB();方法时,因为methodA()àServiceB.methodB()是一个线程中执行的。当前methodA()已经开启事务。MethodB()的传播属性也是:PROPAGATION_REQUIRED。因为它是支持当前事务的。所以它继续用methodA的事务。