MySQL insert on duplicate key update 死锁

来源:这里教程网 时间:2026-03-01 17:03:38 作者:

出现的场景

  • 业务上面临高并发处理,由于数据可能频繁进行写入与更新,因此使用的是insert on duplicate key update语句,在高并发场景下,导致死锁报错

    原因分析

  • 死锁的本质是多个事务等待对方所持有的资源释放,且不会释放自身所持有的资源,导致事务之间循环等待
  • 通过查阅文档以及数据库分析,在on duplicate key时,会在前一个索引值到当前值加临界锁,而多个事务互相等待对方的锁释放,是造成死锁的原因
  • lock_mode X locks gap before rec insert intention waiting

    出现的场景

  • 业务上面临高并发处理,由于数据可能频繁进行写入与更新,因此使用的是insert on duplicate key update语句,在高并发场景下,导致死锁报错

    原因分析

  • 死锁的本质是多个事务等待对方所持有的资源释放,且不会释放自身所持有的资源,导致事务之间循环等待
  • 通过查阅文档以及数据库分析,在on duplicate key时,会在前一个索引值到当前值加临界锁,而多个事务互相等待对方的锁释放,是造成死锁的原因
  • lock_mode X locks gap before rec insert intention waiting

    举例说明

    在以下结构中,value字段存在唯一索引

    ----------------------

        id            value

    ----------------------

        1                1

        3                3

        5                5

    ----------------------

    事务A

    // step1 执行到此处时,由于value=3已存在,此时会对(1,3]加临键锁insert into table(value) values(3) on duplicate key update value = 7;
    // step3 执行到此处时,由于3~5的区间已被锁住,需要等待事务2释放临键锁insert into table(value) values(4) on duplicate key update value = 7;

    事务B

    // step2 执行到此处时,由于value=5已存在,此时会对(3,5]加临键锁insert into table(value) values(5) on duplicate key update value = 8;
    // step4 执行到此处时,由于1~3的区间已被锁住,需要等待事务1释放临键锁insert into table(value) values(2) on duplicate key update value = 8;

    当执行顺序按照step1~step4执行时,便会形成死锁

  • 相关推荐