Spring事务的传播行为
由来
‘“事务的传播行为”,听起来就好高大上的感觉。其实上一篇事务回顾也是为了给这个做铺垫的,我们已经知道事务是怎么回事了,但是得把这个概念真正转换到代码上。我们写代码都知道有controller、service、dao这三层,请求过来先是到达了controller,然后controller去调用service、service再去调用dao。
业务场景
① 假设service1里有一个hello方法,里面分别调用了dao1的hello1方法和dao2的hello2方法。
1
2
3
4
5
6
|
service1{ serviceHello1(){ dao1.daoHello1(); dao2.daoHello2(); } } |
这种情况很常见,在service层serviceHello1方法上加上一个事务A即可。这样就能保证daoHello1和daoHello2方法同时满足事务的四大特性。
② 假设还存在一个service2,里面有一个serviceHello2方法,它里面也分别调用了dao3的daoHello3方法和dao4的daoHello4方法。
1
2
3
4
5
6
|
service2{ serviceHello2(){ dao3.daoHello3(); dao4.daoHello4(); } } |
假设②和假设①一样,只需在service2层serviceHello2方法上加上一个事务B即可。这样就能保证daoHello3和daoHello4方法同时满足事务的四大特性。
③ 假设现在有一个service3,它的业务相对比较复杂,service3里的serviceHello3方法需要同时调用service1和service2里面的方法。
1
2
3
4
5
6
|
service3{ serviceHello3(){ //事务C service1.serviceHello1(); //事务A service2.serviceHello2(); //事务B } } |
现在问题来了,serviceHello3方法上加了一个事务C,那么事务A、B、C能否共用一个事务呢?或者说serviceHello2方法压根没加事务B,它能直接使用事务C吗?等等…诸如此类的各种情况都需要一个标准去统一起来。于是乎,事务的传播行为就诞生了!
Spring中七种事务传播行为(重点①④⑦)
还是用service3这个例子来说明:
1
2
3
4
5
6
|
service3{ serviceHello3(){ //事务C service1.serviceHello1(); //事务A service2.serviceHello2(); //事务B } } |
PROPAGATION_REQUIRED
① 如果事务C存在:
被 PROPAGATION_REQUIRED 修饰的serviceHello1()和serviceHello2()会加入到serviceHello3()的事务中,所有Propagation.REQUIRED修饰的内部方法和外围方法均属于同一事务,只要一个方法回滚,整个事务均回滚。
② 如果事务C不存在:
被 PROPAGATION_REQUIRED 修饰的serviceHello1()和serviceHello2(),会新开启自己的事务A和事务B,且事务A和事务B相互独立,互不干扰。也就是说,事务A只能保证serviceHello1()出异常会回滚,事务B只能保证serviceHello2()出异常会回滚。serviceHello3()如果出异常,不会回滚。
PROPAGATION_REQUIRES_NEW
① 如果事务C存在:
被 Propagation.REQUIRES_NEW 修饰的serviceHello1()和serviceHello2()依然会单独开启事务A和事务B,且与外部方法事务C也独立,内部方法之间、内部方法和外部方法事务均相互独立,互不干扰。
② 如果事务C不存在:
被 Propagation.REQUIRES_NEW 修饰的serviceHello1()和serviceHello2(),会新开启自己的事务A和事务B,且事务A和事务B相互独立,互不干扰。也就是说,事务A只能保证serviceHello1()出异常会回滚,事务B只能保证serviceHello2()出异常会回滚。serviceHello3()如果出异常,不会回滚。
PROPAGATION_NESTED
① 如果事务C存在:
被 Propagation.NESTED 修饰的serviceHello1()和serviceHello2()(事务A和事务B)属于外部事务C的子事务,外围主事务C回滚,子事务A和B一定回滚,而内部子事务A和B可以单独回滚而不影响外围主事务C和其他子事务。
② 如果事务C不存在:
Propagation.NESTED 和 Propagation.REQUIRED 作用相同,修饰的内部方法都会新开启自己的事务A和事务B,事务A和事务B相互独立,互不干扰。
转载:https://blog.csdn.net/fu123123fu/article/details/86359804