环境: jdk 8
框架: mybatis-plus mybaits
先问大家一个问题
下方代码新增 UserVisitor 表 已知 UserVisitor 唯一索引 phone、projectCode、userType 组成 执行后 UserVisitor 数据会保存哪一个手机号?还是都不会保存成功呢?
代码如下:
很简单的几行代码,但是困扰了我一天~
先说结论:都不会保存成功,是由于 saveBatch 方法导致的数据回滚。
原因:
让我们看看 saveBatch 方法的实现
其实就是循环调用了 insert 方法
需要注意的是 saveBatch 方法上 额外声明了 Transactional 事务注解。并切 隔离机制是默认的 Propagation.REQUIRED 如果已有事务就沿用。
已知此时如果里面的方法执行出现错误 被 try 包裹了 理应是不会 rollback 但是!! 注意 如果又通过 aop 调用了下一级方法 并切传播依赖是 Propagation.REQUIRED 就会导致外层的事务也 回滚 !!!
ok 那在继续跟进
手动 获取当前事务 并且 里层还有一个 catch 块 进行了事务回滚 按照事务传播机制 外层的数据也就被回滚了。
执行后的结果
不过 注意下 mybatisPlus 的作者 的注释。3.3.1后面的版本 这个方法 会被替换
答疑: 如果 try 包裹后的方法 就算开启了事务 在下一集的方法栈 中 是否会导致 外层调用 rollback呢?
为了避免大家的疑问。给出下方测试案例
重载了一下 saveBacth 方法
外层test调用如下
执行结果如下
也是一样会回滚的~
~ 疑问解答 ~
解决方案:
如果 改成 此模式进行 save 操作 并不会影响 调用方 uv表的数据写入
或者将事务传播依赖级别改成:REQUIRES_NEW
一道简单的 事务传播级别问题导致的问题~