呈现的场景

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

起因剖析

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

举例说明

在以下构造中,value字段存在惟一索引

事务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执行时,便会造成死锁

相干陈说性知识 & 官网文档 & 集体了解

  • InnoDB Locking
  • MySql的锁