Spring事务(二)-事务的传播行为

本文深入探讨了事务传播行为在多层调用中的作用,详细解释了Spring中七种事务传播行为,包括PROPAGATION_REQUIRED、PROPAGATION_REQUIRES_NEW和PROPAGATION_NESTED等,及其在不同场景下的应用。

由来

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

业务场景
① 假设service1里有一个hello方法,里面分别调用了dao1的hello1方法和dao2的hello2方法。

service1{
	serviceHello1(){
		dao1.daoHello1();
		dao2.daoHello2();
	}
}

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

② 假设还存在一个service2,里面有一个serviceHello2方法,它里面也分别调用了dao3的daoHello3方法和dao4的daoHello4方法。

service2{
  	serviceHello2(){
  		dao3.daoHello3();
  		dao4.daoHello4();
  	}
}

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

③ 假设现在有一个service3,它的业务相对比较复杂,service3里的serviceHello3方法需要同时调用service1和service2里面的方法。

service3{
	serviceHello3(){//事务C
    	service1.serviceHello1();//事务A
    	service2.serviceHello2();//事务B
	}
}

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

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

事务传播行为类型说明
① PROPAGATION_REQUIRED 支持当前事务,如果不存在,就创建一个
② PROPAGATION_SUPPORTS支持当前事务,如果不存在,就不使用事务
③ PROPAGATION_MANDATORY支持当前事务,如果不存在,就抛出异常
④ PROPAGATION_REQUIRES_NEW如果有事务存在,挂起当前事务,创建一个新的事务
⑤ PROPAGATION_NOT_SUPPORTED以非事务方式运行,如果有事务存在,挂起当前事务
⑥ PROPAGATION_NEVER以非事务方式运行,如果有事务存在,抛出异常
⑦ PROPAGATION_NESTED如果当前事务存在,则嵌套事务执行

还是用service3这个例子来说明:

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相互独立,互不干扰。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值