mybatis-plus 批量插入时事务失效

发布于 2022-05-25 07:50:29 字数 365 浏览 954 评论 12

各位大佬,小弟最近开发的时候碰到一个很诡异的问题,如下:

首先是一个接口,这个接口里面有两个方法,分别是方法A和方法B,在方法A中使用mybatis-plus提供的批量插入API,saveOrUpdateBatch,成功批量插入了C表数据,然后在方法B中查询方法A批量插入的C表数据,发现查不到,然后拿日志打印的查询语句去数据库执行,是可以查到数据的。

之后,我尝试着在方法A中把批量插入改成for循环一个一个插入,然后方法B不变,这回就可以查询到A方法中插入的C表数据了。

事后,小弟排除了很多可能,包括方法B的查询条件是否错误,方法A批量插入的数据是否有误,包括事务配置,这些均没有发现有不对的地方,不知道是我哪里配置不对,还是mybatis-plus本身的问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

温馨耳语 2022-05-28 05:35:03

1、saveOrUpdateBatch(…)方法也是循环生成insert语句,你可以优化成一条insert语句(这是MyBatis优势之一)。

2、先插后查不到,不在一个session里、DB就没及时处理等有关。

3、MyBatis里的方法都是一个方法一个事务,所以,不在一个session管道里。(JPA不注解也是如此)

 

ま昔日黯然 2022-05-28 05:35:00

 

事务本身是aop实现的吧

试一下AopContext.currentProxy()这样处理呢

https://blog.csdn.net/qq_29860591/article/details/108728150

霞映澄塘 2022-05-28 05:34:51

试了下,还是不行

丘比特射中我 2022-05-28 05:34:24
saveOrUpdateBatch的时候指定batchSize
心清如水 2022-05-28 05:34:19

listHandinMat只是一个简单的QueryWrapper条件查询,倒没看到有什么问题:joy:

追星践月 2022-05-28 05:30:57

问题多半在这个listHandinMat方法里面。仔细检查代码把,多半是一些低级的问题导致的。

 
破晓 2022-05-28 05:30:07

A方法和B方法都是同一个service的不同接口 A方法中的List<WxHandinMat> handinMats = listHandinMat(applyId, busType, false);和B方法中的List<WxHandinMat> wxHandinMats = listHandinMat(applyId, busType, false);是同一个接口

久隐师 2022-05-28 05:25:49
<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);
                }
            }
        }
    }

B方法:

@Override
public void resetHandinMatIsEss(String applyId, String busType) {
    List<WxHandinMat> wxHandinMats = listHandinMat(applyId, busType, false);
    if (!CollectionUtils.isEmpty(wxHandinMats)) {
        // TODO
    }
}
不醒的梦 2022-05-28 05:17:43

mybatis-plus本身的问题概率不大,因为你的描述是常见需求,要出问题早出问题了。

其次,你可以吧你的代码脱敏,贴出来,大家一起集思广益。

像极了他 2022-05-28 05:14:02

我认为主从分离的可能性不大,因为问题的标签上是Oracle而不是MySQL。Oracle有钱做主从分离,那干嘛不干脆再稍微加一点,直接RAC?!

╄→承喏。◢ 2022-05-28 04:18:33

不确定你的具体配置,但可能有这么几个问题

1,做了主从分离,查询的时候从库还没有同步,等你复制好语句的时候从库已经同步了

2、事务,你的A方法和B方法不再同一个事务之中导致的。也可能你的A方法和B方法采用的事务策略是新建事务,导致查不到

 

小…红帽 2022-05-28 03:45:18

继续检查事务配置,包括你程序事务设定和数据库隔离等级,这个问题大概率是A和B不在一个事务。A执行后还没有提交事务,B就执行了,所以B查不到A的。

你一个个插入,那可能就是插1个提交了一次事务,于是B就拿到了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文