INSERT操作能并发执行,是因为插入意向锁将间隙冲突检测从粗粒度降为细粒度位置探测:多个事务可同时对同一gap加该锁,只要插入位置不重叠且不撞上现有记录锁或间隙锁;它本质是Gap Lock的兼容变体,不解决唯一键冲突,空表高并发插入易因隐式gap争抢引发死锁。

INSERT 操作能并发执行,不是因为插入意向锁“放行”了所有插入,而是它把「探路」动作从粗粒度的间隙互斥,降级为细粒度的位置探测——多个事务可以同时对同一个 gap 加 INSERT_INTENTION 锁,只要它们不落在同一行、不撞上已有记录锁或间隙锁。
Insert Intention Lock 本质是 Gap Lock 的兼容变体
它和普通 GAP LOCK 共享范围(比如 (10, 20)),但加锁逻辑不同:
- 普通
GAP LOCK是排他的:一旦事务 A 对(10, 20)加了GAP LOCK,其他事务再想往这个区间插任何值,都会被阻塞 -
INSERT_INTENTION锁是“声明式”的:事务 A 插 15、事务 B 插 18,两者都对(10, 20)加该锁,InnoDB 内部判定它们不冲突,直接允许并发 - 它不解决唯一键冲突:如果两个事务都插
id_card = '123'(该字段有唯一索引),其中一个会在目标记录上尝试加S LOCK做 duplicate key 检查,另一个被X LOCK阻塞,极易死锁
为什么空表高并发 Insert 会死锁?
空表没有实际记录,所有插入都落在同一个隐式 gap 上——比如主键自增,初始 gap 是 (-∞, +∞)。这时多个事务申请同一个 gap 的 INSERT_INTENTION 锁,虽不直接互斥,但 MySQL 的锁等待队列机制可能让它们形成循环等待:
- 事务 A 等待事务 B 释放对
(-∞, +∞)的插入意向锁(因 B 占位未提交) - 事务 B 同样在等 A,最终触发
Deadlock found when trying to get lock - 这不是锁设计缺陷,而是高并发下锁资源争抢的自然结果;
innodb_deadlock_detect=ON会主动干掉一个事务来破环
怎么验证当前有没有 Insert Intention Lock?
只能通过 SHOW ENGINE INNODB STATUS\G 查看,搜索 LOCK_MODE = 'INSERT_INTENTION' 字段:
- MySQL 5.7+ 支持该输出;8.0 中部分信息移至
performance_schema.data_locks表 - 注意:该锁是瞬时的——插入成功后立即升级为记录
X LOCK,失败回滚则释放;所以抓取窗口很窄 - 不要指望
information_schema.INNODB_TRX或INNODB_LOCK_WAITS显示它,这些表不暴露插入意向锁


















