mybatis-plus 批量插入时事务失效
source link: https://www.oschina.net/question/5451389_2324209
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
mybatis-plus 批量插入时事务失效
各位大佬,小弟最近开发的时候碰到一个很诡异的问题,如下:
首先是一个接口,这个接口里面有两个方法,分别是方法A和方法B,在方法A中使用mybatis-plus提供的批量插入API,saveOrUpdateBatch,成功批量插入了C表数据,然后在方法B中查询方法A批量插入的C表数据,发现查不到,然后拿日志打印的查询语句去数据库执行,是可以查到数据的。
之后,我尝试着在方法A中把批量插入改成for循环一个一个插入,然后方法B不变,这回就可以查询到A方法中插入的C表数据了。
事后,小弟排除了很多可能,包括方法B的查询条件是否错误,方法A批量插入的数据是否有误,包括事务配置,这些均没有发现有不对的地方,不知道是我哪里配置不对,还是mybatis-plus本身的问题。
继续检查事务配置,包括你程序事务设定和数据库隔离等级,这个问题大概率是A和B不在一个事务。A执行后还没有提交事务,B就执行了,所以B查不到A的。
你一个个插入,那可能就是插1个提交了一次事务,于是B就拿到了。
<tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="find*" propagation="SUPPORTS" read-only="true"/> <tx:method name="select*" propagation="SUPPORTS" read-only="true"/> <tx:method name="search*" propagation="SUPPORTS" read-only="true"/> <tx:method name="del*" rollback-for="java.lang.Exception"/> <tx:method name="delete*" rollback-for="java.lang.Exception"/> <tx:method name="insert*" rollback-for="java.lang.Exception"/> <tx:method name="update*" rollback-for="java.lang.Exception"/> <tx:method name="save*" rollback-for="java.lang.Exception"/> <tx:method name="*" rollback-for="java.lang.Exception"/> </tx:attributes> </tx:advice>
这个是事务的部分配置,有尝试在在name="*"的那一行加上
propagation="SUPPORTS"
也是不生效。
以下是相关的代码:
最外层的接口:
// 拷贝申请材料数据 wxHandinMatService.copyTrMatBasToWechat(applyId, busType, applyInfo.getSenderOrigin(), applyUserId); // 根据业务内容重置必上传属性 wxHandinMatService.resetHandinMatIsEss(applyId, busType);
A方法:
@Override public void copyTrMatBasToWechat(String applyId, String busType, String senderOrigin, String applyUserId) { List<WxHandinMat> handinMats = listHandinMat(applyId, busType, false); // 如果为空,则拷贝 if (CollectionUtils.isEmpty(handinMats)) { // TODO List<TrMatBas> trMatBasList = trMatBasService.listByBusType(busType, senderOrigin); if (!CollectionUtils.isEmpty(trMatBasList)) { List<WxHandinMat> list = new ArrayList<>(); for (TrMatBas matBas : trMatBasList) { WxHandinMat handinMat = new WxHandinMat(); // TODO list.add(handinMat); } // 这里批量插入之后,B方法查询不到 if (!CollectionUtils.isEmpty(list)) { // for (WxHandinMat handinMat : list) { // saveOrUpdate(handinMat); // 单独一个一个插入,B方法可以查询到 // } saveOrUpdateBatch(list); } } } }
@Override public void resetHandinMatIsEss(String applyId, String busType) { List<WxHandinMat> wxHandinMats = listHandinMat(applyId, busType, false); if (!CollectionUtils.isEmpty(wxHandinMats)) { // TODO } }
1、saveOrUpdateBatch(…)方法也是循环生成insert语句,你可以优化成一条insert语句(这是MyBatis优势之一)。
2、先插后查不到,不在一个session里、DB就没及时处理等有关。
3、MyBatis里的方法都是一个方法一个事务,所以,不在一个session管道里。(JPA不注解也是如此)
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK