Spring事务传播机制大白话(使用springboot,注解演示)

1. 我对传播机制的理解

  1. 为什么需要传播机制?
    因为事务之间可能存在相互调用,例如service业务层的方法存在相互调用,如果相互调用的方法都开启了事务(对应到springboot就是在方法上要添加@Transactional注解),那么程序需要以什么样的策略来执行事务呢?因此需要我们指定好事务传播机制,程序遇到这种情况就可以根据我们事先指定好的传播机制来执行。
    在这里插入图片描述

2. spring其中事务传播机制

默认的事务传播机制是required,点进注解看源码:
在这里插入图片描述

事务传播行为类型说明
PROPAGATION_REQUIRED如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。
PROPAGATION_SUPPORTS支持当前事务,如果当前没有事务,就以非事务方式执行
PROPAGATION_MANDATORY使用当前的事务,如果当前没有事务,就抛出异常。
PROPAGATION_REQUIRES_NEW新建事务,如果当前存在事务,把当前事务挂起。
PROPAGATION_NOT_SUPPORTED以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
PROPAGATION_NEVER以非事务方式执行,如果当前存在事务,则抛出异常。
PROPAGATION_NESTED如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与PROPAGATION_REQUIRED类似的操作。
3. 实验验证
3.1. NEVER
3.1.1 调用方不开启事务(不添加Transactional注解)

代码如下,在controller调用service方法,实验前id=3的用户开始的money是1000,正常情况下想把其money更新为900
在这里插入图片描述
代码如下:
在这里插入图片描述
Controller中testTransaction去调用service中的testTransaction,可以看到右侧被调用的方法上边传播机制设置的NEVER,执行后效果如下:
在这里插入图片描述
在这里插入图片描述

发现当Controller层不加Transactional注解,Service层的testTransaction方法上添加Transactional并且把传播机制设置为NEVEL后,事务并没有生效,执行完后抛出了异常,但是数据库还是写进去了。

每次做完实验记得把数据库的900还原成1000;

3.1.2 调用方开启事务(添加Transactional注解)

在这里插入图片描述
请求执行后可以看到直接抛出了异常, Existing transaction found for transaction marked with propagation ‘never’,说明调用方式不能有事务的,如果有就直接抛出上图种的异常,并且Service层的业务代码并没有执行,没有抛出 除以0的异常。

3.1.3 总结

NEVEL传播机制,要求调用方不能有事务,在本测试中表现就是Ctroller中的testTransaction方法上不能有事务的注解

3.2. REQUIRED
3.2.1 service层的传播机制设置为required

service层的传播机制设置为required时,无论Controller层开启或者不开启事务,结果都是如下:
在这里插入图片描述
在这里插入图片描述

3.2.2 结论

说明当被调用方开启了事务,并且传播机制是required的时,一定会以事务的方式执行,具体表现就是如上边的图示,代码抛出了异常 / by zero,同时数据库中并没有写入900,说明异常后数据回滚了。

其他的就不再一一测试了,都是一个道理,始终记住列表中说的“当前事务”指的是调用方。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值