黑马程序员技术交流社区

标题: Spring事务的传播行为 [打印本页]

作者: 小江哥    时间: 2019-11-6 19:28
标题: Spring事务的传播行为
由来
‘“事务的传播行为”,听起来就好高大上的感觉。其实上一篇事务回顾也是为了给这个做铺垫的,我们已经知道事务是怎么回事了,但是得把这个概念真正转换到代码上。我们写代码都知道有controller、service、dao这三层,请求过来先是到达了controller,然后controller去调用service、service再去调用dao。

业务场景
① 假设service1里有一个hello方法,里面分别调用了dao1的hello1方法和dao2的hello2方法。
[Java] 纯文本查看 复制代码
service1{
        serviceHello1(){
                dao1.daoHello1();
                dao2.daoHello2();
        }
}

这种情况很常见,在service层serviceHello1方法上加上一个事务A即可。这样就能保证daoHello1和daoHello2方法同时满足事务的四大特性。

② 假设还存在一个service2,里面有一个serviceHello2方法,它里面也分别调用了dao3的daoHello3方法和dao4的daoHello4方法。
[Java] 纯文本查看 复制代码
service2{
          serviceHello2(){
                  dao3.daoHello3();
                  dao4.daoHello4();
          }
}

假设②和假设①一样,只需在service2层serviceHello2方法上加上一个事务B即可。这样就能保证daoHello3和daoHello4方法同时满足事务的四大特性。

③ 假设现在有一个service3,它的业务相对比较复杂,service3里的serviceHello3方法需要同时调用service1和service2里面的方法。
[Java] 纯文本查看 复制代码
service3{
        serviceHello3(){//事务C
            service1.serviceHello1();//事务A
            service2.serviceHello2();//事务B
        }
}

现在问题来了,serviceHello3方法上加了一个事务C,那么事务A、B、C能否共用一个事务呢?或者说serviceHello2方法压根没加事务B,它能直接使用事务C吗?等等…诸如此类的各种情况都需要一个标准去统一起来。于是乎,事务的传播行为就诞生了!

Spring中七种事务传播行为(重点①④⑦)

还是用service3这个例子来说明:
[Java] 纯文本查看 复制代码
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






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2