MySQL Lock--并发插入导致的死锁

============================================================================

测试脚本:

表结构:
CREATE TABLE `t1` (
`i` int(11) NOT NULL DEFAULT '0',
PRIMARY KEY (`i`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

会话1:
begin;
INSERT INTO t1 VALUES(1);

会话2:
begin;
INSERT INTO t1 VALUES(1);


会话3:
begin;
INSERT INTO t1 VALUES(1);


会话1执行ROLLBACK,会话2和会话3产生死锁

============================================================================

案例分析

案例分析:
当会话1未提交时,对插入的记录持有X排它锁,会话2和会话2检测到记录存在,但由于会话1处于未提交状态,不能判定会话2和会话3主键冲突, 会话2和会话3的执行成功与否取决于会话1提交还是回滚,因此会话2和会话3改为申请该记录的共享锁,由于记录上有X排他锁,因此会话2和会话3等待共享锁。

等会话1发生回滚,会话2和会话3会立即获得共享锁,然后会话2和会话3分别尝试插入,申请对记录持有X排他锁,因为对方会话持有S共享锁,申请X排他锁锁被阻塞,引发死锁检查并触发死锁。

参考: INSERT加锁规则

原文地址:https://www.cnblogs.com/gaogao67/p/10412249.html