============================================================================
测试脚本:
表结构: 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加锁规则