A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 小江哥 黑马粉丝团   /  2019-11-6 19:28  /  813 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

由来
‘“事务的传播行为”,听起来就好高大上的感觉。其实上一篇事务回顾也是为了给这个做铺垫的,我们已经知道事务是怎么回事了,但是得把这个概念真正转换到代码上。我们写代码都知道有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中七种事务传播行为(重点①④⑦)
1.png
还是用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

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马