一个事务传播机制带来的生产事故

环境: jdk 8
框架: mybatis-plus mybaits

先问大家一个问题
下方代码新增 UserVisitor 表 已知 UserVisitor 唯一索引 phone、projectCode、userType 组成 执行后 UserVisitor 数据会保存哪一个手机号?还是都不会保存成功呢?
代码如下:
image

很简单的几行代码,但是困扰了我一天~

先说结论:都不会保存成功,是由于 saveBatch 方法导致的数据回滚。

原因:

让我们看看 saveBatch 方法的实现
image
其实就是循环调用了 insert 方法
需要注意的是 saveBatch 方法上 额外声明了 Transactional 事务注解。并切 隔离机制是默认的 Propagation.REQUIRED 如果已有事务就沿用。
已知此时如果里面的方法执行出现错误 被 try 包裹了 理应是不会 rollback 但是!! 注意 如果又通过 aop 调用了下一级方法 并切传播依赖是 Propagation.REQUIRED 就会导致外层的事务也 回滚 !!!

ok 那在继续跟进
image
image
手动 获取当前事务 并且 里层还有一个 catch 块 进行了事务回滚 按照事务传播机制 外层的数据也就被回滚了。

执行后的结果
image
image
不过 注意下 mybatisPlus 的作者 的注释。3.3.1后面的版本 这个方法 会被替换

image

答疑: 如果 try 包裹后的方法 就算开启了事务 在下一集的方法栈 中 是否会导致 外层调用 rollback呢?

为了避免大家的疑问。给出下方测试案例

image
重载了一下 saveBacth 方法
外层test调用如下
image
执行结果如下
image
也是一样会回滚的~

~ 疑问解答 ~

解决方案:
image
如果 改成 此模式进行 save 操作 并不会影响 调用方 uv表的数据写入

或者将事务传播依赖级别改成:REQUIRES_NEW

一道简单的 事务传播级别问题导致的问题~

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值