在循环中插入MySql数据库而不发生死锁

在循环中插入MySql数据库而不发生死锁,mysql,node.js,async-await,transactions,deadlock,Mysql,Node.js,Async Await,Transactions,Deadlock,我使用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 MO

我使用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
并行运行查询,所以上面的代码抛出错误:
在尝试获取锁时发现死锁;尝试重新启动事务
。如果我使用同步循环的for运行它,它工作正常。 如何修复此问题或我的脚本的任何想法。对不起,我的英语不好

顺便说一句,我使用
LOCK IN SHARE MODE
FOR UPDATE
来避免在运行许多查询
INSERT
时出现重复,即使我使用
findOrCreate
来检查行是否存在

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

选择。。。锁定共享模式

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

选择。。。更新


对于搜索遇到的索引记录,锁定行和任何关联的索引项,就像为这些行发出UPDATE语句一样。其他事务被阻止更新这些行,无法执行选择。。。锁定在共享模式下,或从某些事务隔离级别读取数据。一致读取忽略在读取视图中存在的记录上设置的任何锁。(记录的旧版本无法锁定;它们是通过在记录的内存副本上应用撤消日志重建的。)

我找到了一个临时解决方案:使用
插入忽略
而不是
插入
。
因此,我删除了
选择
查询并使用
插入忽略

const language = await Database.raw(trx('languages').insert({
      ...languageItem,
      created_at: this.getTimeNow(),
      updated_at: this.getTimeNow()
}).toString().replace('insert', 'INSERT IGNORE'));

我的脚本运行时没有死锁。

我已经尝试了更新
,仍然是相同的错误。我认为这里的问题是
eachOfLimit
同时运行多个查询
SELECT
,所以它们锁定同一行。