Spring事务传播行为(举例说明)

本文详细探讨了事务的六种传播属性,通过实例展示了REQUIRED、REQUIRES_NEW、SUPPORTS、MANDATORY、NOT_SUPPORTED和NEVER在StockService和stockMapper中的应用,揭示了不同传播级别对事务执行的影响和回滚规则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

临时起意对传播行为的几种属性做了一下测试。

首先看下面这张图对事务的其中传播属性做的说明(前两种应该用的比较多),下面对每种传播行为的结果做一下举例

下面的实验以这两个service中的addconsumer1和decreaseStock方法以及stockMapper
中的decreaseStock为核心进行实验,具体做法是在StockServiceImpl的一个
decreaseStock方法中(外部事务)调用了stockMapper.decreaseStock方法来让库存减一,
且调用addconsumer1方法(内部事务)来添加用户

1.REQUIRED
如果当前存在事务,那么就加入该事务:比如下图中两个方法都用@Transactional修饰,那么
执行的时候这两个事务会合并成一个事务。下图测试的结果是当外部事务中发生异常,内部
事务也会跟着回滚。数据表不发生变化
如果当前没有事务,则创建一个新事务:还是下图的例子,当@decreaseStock方法不加
@Transaction注解的时候,就会出现第一次的减库存decreaseStock执行成
功,addconsumer1由于是自己创建的事务,所以数据也添加成功,而第二次减库存操作之前由
于发生了运行时异常,所以不生效

2.REQUIRES_NEW
创建一个新的事务,如果当前存在事务,则把当前事务挂起:还是下面的例子:还是1中的例子,
只是把
@Transaction中的propagation改了成了REQUIRES_NEW,此时外部事务decreaseStock
发生了异常回滚,不会影响到内部事务,因为addconsumer1创建了一个新事务 

3.SUPPORTS
如果当前存在事务,就加入该事务,如果没有事务,就以非事务的方式继续运行:比如此时
addconsumer1方法设置了Propagation.SUPPORTS,然后decreaseStock把
@Transacitonal注解注释掉了,那么此时就相当于这两个方法都不进行事务处理。那么下图
的结果就是第一次的decreaseStock和addconsumer1生效,第二次的decreaseStock不生
效。如果deceaseStock方法加了@Transactional注解开启了事务,那么此时两个方法走同
一个事务 

4.MANDATORY
有事务运行就加入,没有就抛异常。比如addconsumer1方法开启了MANDATORY级别的传
播属性,而decreaseStock方法没加@Transactional注解,此时运行就会报错,因为
addconsumer1方法没有运行在事务内


5.NOT_SUPPORTED
以非事务方式运行,如果当前存在事务,则将该事务挂起:我在内部事务方法中设置了
NOT_SUPPORTED传播级别,通过debug可以发现,外部事务还没提交,内部addconsumer1
方法已经对数据库的数据进行了修改

6.NEVER

如果当前存在事务就抛出异常,这个就很好理解不做演示了

7.NESTED

外部有事务,此时内部事务作为当前事务的嵌套事务来执行,发生的异常在外部捕获,此时,addconsumer1对数据库的修改回滚,decreaseStock正常执行。

这里可以特别注意一下和两个方法都设置成REQUIRED的区别:同样的测试代码,如果都换成REQUIRED,此时会因为内部事务异常没有在内部捕获,而导致内部和外部整个事务回滚,也就是说decreaseStock和addconsumer1都不生效

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值