mybatis plus saveBatch 踩坑

1,066 阅读1分钟

最近生产环境经常出现一个奇怪现象,同一个spring事务内,新增数据和更新数据不是原子性的; 这个接口伪代码大致是以下这样的

开启本地事务;
try{
    计算并保存负记录;
    扣费;
    更新正记录;
    提交事务;
}catch(Exception e){
    回滚事务
}

线上经常出现 负记录没有保存成功,而正记录修改成功,无论是spring声明式事务还是编程式事务都会偶尔出现; 感觉保存负记录和其他逻辑并不在同一个事务内,经过分析代码,保存负记录使用的是mybatis-plus的saveBatch方法; 源码如下:

@Transactional(rollbackFor = Exception.class)
default boolean saveBatch(Collection<T> entityList) {
    return saveBatch(entityList, DEFAULT_BATCH_SIZE);
}

发现saveBatch会自己开启一个事务导致不一致的情况,后来通过把批量保存改成sql方式,修复问题

外层事务

image.png

内层事务

image.png