insert on duplicate key update死锁

MySQL的insert on duplicate 逻辑是,先插入主键,再插唯一键,如果唯一键发生冲突会出现加next-key锁,然后进行一次回滚(要回滚写入到主键的记录),此时刚刚插入的遗留在主键记录的锁(MySQL的隐式锁机制)退化成了gap锁(因为主键上的记录不再需要了),锁的范围就退化成主键的最后到无穷大,在批量更新场景下,也许会有另外一个行数据插入到最后,还会有一把插入意向锁,此时死锁。


无论是死锁还是锁放大,根源在于锁的范围扩大了。为什么范围扩大了,因为sql语句种,无论是replace还是insert 之类,都会在插入或者更新前,先去判断下是不是这个b树上有唯一值存在。因为b树里存在大量的被标记为删除但是还未真正删除的记录,在检查唯一值的时候,就需要把这些全部先锁住,以及这些前后以及间隙都锁住,造成了锁范围放大。所以建议大家还是最好不要用这个语法。如果一定要用insert on duplicate,避免死锁的解法就是一次只更新一行。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值