数据库死锁的问题,Deadlock found when trying to get lock; try restarting transaction at Query.formatError[通俗易懂]

数据库死锁的问题,Deadlock found when trying to get lock; try restarting transaction at Query.formatError[通俗易懂]场景:应用刚上线排除大批量请求的问题线上多次出现的Deadlock found when trying to get lock错误代码:async batchUpdate(skus, { transa

  • 场景:

    • 应用刚上线排除大批量请求的问题
    • 线上多次出现的Deadlock found when trying to get lock错误

    数据库死锁的问题,Deadlock found when trying to get lock; try restarting transaction at Query.formatError[通俗易懂]

  • 代码:

async batchUpdate(skus, { transaction }) {
    const result = await Promise.all(skus.map(async sku => {
      const record = await this.app.model.Sku.upsert(sku, { transaction });
      return record;
    }));

    // SaaS 中删掉的 sku,插件也要同步删除
    const ids = _.map(skus, 'sku_id');
    const productIds = _.map(skus, 'product_id');
    const { Op } = this.app.Sequelize;
    
    await this.app.model.Sku.destroy({
      where: {
        sku_id: { [Op.notIn]: ids },
        product_id: productIds,
      }, transaction,
    });

    return result;
  };

代码100分

  • 分析:

    • 报错位置都是在this.app.model.Sku.destroy的时候报错
    • Deadlock found when trying to get lock的原因是多个事物同事更新插入同一表的某一段数据
    • 在数据量不大的情况下,按道理说发生这种死锁的情况应该非常少但是事实上出现的概率很高
  • 结论:

    • 应该是destroy使用notIn会涉及到很多行的锁定,所以造成了死锁。但是业务上destroy删除的数据一般为0条。所以可以只在必要的时候进行destroy操作。
    • 更新的时候少用或不用notIn操作
  • 优化后代码:

代码100分  async batchUpdate(skus, { transaction }) {
    const result = await Promise.all(skus.map(async sku => {
      const record = await this.app.model.Sku.upsert(sku, { transaction });
      return record;
    }));

    // SaaS 中删掉的 sku,插件也要同步删除
    const ids = _.map(skus, 'sku_id');
    const productIds = _.map(skus, 'product_id');
    const { Op } = this.app.Sequelize;
    const delSkus = await this.app.model.Sku.findAll({
      where: {
        sku_id: { [Op.notIn]: ids },
        product_id: productIds,
      }, transaction,
    });
    if (delSkus && delSkus.length) {
      await this.app.model.Sku.destroy({
        where: {
          sku_id: delSkus.map(sku => sku.sku_id),
        }, transaction,
      });
    }

    return result;
  };

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
转载请注明出处: https://daima100.com/10725.html

(0)
上一篇 2022-12-22
下一篇 2022-12-22

相关推荐

  • 使用命令行从Python运行.py文件

    使用命令行从Python运行.py文件在实际开发过程中,我们可能会需要通过命令行运行Python文件,这种方式有其独特的优点。例如,命令行运行可以方便我们对脚本进行参数传递,调试过程更加直观,还可以在Linux服务器上运行Python代码。

    2024-02-22
    88
  • 用Python的字符串join方法将列表合并成字符串

    用Python的字符串join方法将列表合并成字符串在Python中,字符串是一种不可变的序列类型,而列表是一种可变的序列类型。在实际编程中,经常需要将多个字符串或者列表拼接成一个字符串。Python提供了多种方法来实现这一目的,其中最常用的方式是使用字符串的join方法。该方法接受一个可迭代对象作为参数,并将其元素以指定的分隔符连接成一个字符串。

    2024-02-28
    42
  • redis查询速度慢_redis读取速度

    redis查询速度慢_redis读取速度当Redis客户端出现请求超时的时候,需要检查该时间点是否有慢查询,从而分析出由于慢查询导致的命令级联阻塞。

    2023-02-19
    104
  • 查杀oracle的阻塞「终于解决」

    查杀oracle的阻塞「终于解决」查杀oracle的阻塞 cuihengju8933 2018-07-22 20:12:32 42 收藏 执行以下脚本抓目前的阻塞: select (select username||':&…

    2023-03-15
    114
  • 用Python读取文件的方法

    用Python读取文件的方法Python是一种高效的编程语言,具有易学、代码可读性强、能够快速完成复杂任务等特点,在数据分析、机器学习等领域广泛应用。在Python编程过程中,读取文件是必不可少的一环,本文将详细介绍Python读取文件的方法。

    2024-05-06
    12
  • SQL Server 查看当前会话状态【sp_WhoIsActive 转载】

    SQL Server 查看当前会话状态【sp_WhoIsActive 转载】一.常见简便的方式 通常,DBA使用sp_who和sp_who2系统存储过程或活动监视器来查看SQL实例中的当前会话、用户和进程。 我们还可以从这些过程中确定阻塞会话和活动会话。 1.1. Sp_wh

    2023-04-18
    139
  • sonarqube配置全指南,集成阿里巴巴p3c规范

    sonarqube配置全指南,集成阿里巴巴p3c规范环境准备 内置数据库 Sonar安装成功后,默认内置H2数据库,用于记录单次的扫描结果,对同一个project重复扫码,会覆盖之前的扫描记录,所以H2 数据库只应用于测试,不可以用于生产环境,那如果你

    2023-02-05
    98
  • 推荐两个MySQL学习资源

    推荐两个MySQL学习资源1. 《深入理解MySQL主从复制32讲》专栏 高鹏(八怪)的《深入理解MySQL主从复制32讲》专栏此前在知数堂的平台上连载,不过我们使用的有赞平台服务到期后就没再续费了,因此转战到简书了。 高鹏…

    2023-02-23
    101

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注