在没有死锁的情况下循环插入MySql数据库

问题描述 投票:1回答:1

im使用nodejs(AdonisJs)创建脚本来更新我的数据库(Mysql)。像这样的东西:

const trx = await Database.beginTransaction();
try {
    const async = use('async');

    await async.eachOfLimit(arr, 50, async item => {
        `select * from table1 where id = 1 LOCK IN SHARE MODE`
        `insert into ....`
        `another query...`
    });
    trx.commit();
} catch (err) {
    trx.rollback();
}

问题是eachOfLimit并行运行查询,因此上面的代码引发错误:Deadlock found when trying to get lock; try restarting transaction。如果我使用for of同步循环运行它,则工作正常。如何为我的脚本解决此问题或任何想法。对不起,我的英语不好。

mysql node.js async-await transactions deadlock
1个回答
1
投票

您可以尝试使用“ FOR UPDATE”而不是“ LOCK IN SHARE MODE”来防止在同一行上进行锁定。

来自dev.mysql.com

选择...以共享模式锁定

在读取的任何行上设置共享模式锁定。其他会话可以读取行,但是在事务提交之前不能修改它们。如果这些行中的任何一个被尚未提交的另一个事务更改,则查询将等待该事务结束,然后使用最新值。

选择...进行更新

对于索引记录搜索遇到的问题,锁定行和任何关联的索引条目,就像您对那些行发出UPDATE语句一样。禁止其他事务更新这些行,执行SELECT ... LOCK IN SHARE MODE或读取某些事务隔离级别的数据。一致的读取将忽略读取视图中存在的记录上设置的任何锁定。 (记录的旧版本无法锁定;可以通过在记录的内存副本上应用撤消日志来重构它们。)

© www.soinside.com 2019 - 2024. All rights reserved.