Skip to content

插入意向锁 (Insert Intention Lock) ​

📋 概述 ​

插入意向锁(Insert Intention Lock)是 MySQL InnoDB 引擎在 INSERT 操作时使用的一种特殊锁。它本质上是一种特殊的间隙锁,用于表明事务打算在某个间隙中插入记录。

核心特点 ​

✅ 优点:

  • 提高并发: 多个事务可以在不同位置并发插入
  • 冲突检测: 快速检测插入冲突
  • 自动管理: InnoDB 自动处理
  • 死锁预防: 帮助检测和预防死锁

❌ 缺点:

  • 理解复杂: 概念较抽象
  • 可能死锁: 与间隙锁交互时可能死锁
  • 仅 InnoDB: MySQL InnoDB 特有

适用场景 ​

  • INSERT 操作: 所有插入操作
  • 并发插入: 多个事务同时插入
  • 唯一索引检查: 检查唯一约束冲突
  • 间隙锁共存: 与间隙锁的交互场景

🔧 工作原理 ​

锁的本质 ​

插入意向锁是一种特殊的间隙锁,但与普通间隙锁不同:

  • 普通间隙锁: 阻止其他事务插入
  • 插入意向锁: 表明"我打算在这里插入"

工作流程 ​

sql
-- 假设表中有 id = 1, 5, 10 的记录
-- 间隙为: (1, 5), (5, 10)

-- 事务 A
INSERT INTO users VALUES (3, 'john');
-- 在间隙 (1, 5) 上加插入意向锁

-- 事务 B(同时)
INSERT INTO users VALUES (7, 'jane');
-- 在间隙 (5, 10) 上加插入意向锁
-- ✅ 不冲突,可以并发执行

与间隙锁的交互 ​

sql
-- 事务 A
BEGIN;
SELECT * FROM users WHERE id = 5 FOR UPDATE;
-- 锁定间隙 (1, 5) 和 (5, 10)(间隙锁)

-- 事务 B
INSERT INTO users VALUES (3, 'john');
-- ❌ 被阻塞!插入意向锁与间隙锁冲突

💻 MySQL InnoDB 实现 ​

查看插入意向锁 ​

sql
-- 查看插入意向锁
SELECT 
    lock_id,
    lock_trx_id,
    lock_mode,
    lock_type,
    lock_table,
    lock_index,
    lock_data
FROM performance_schema.data_locks
WHERE lock_mode = 'X,GAP';  -- 插入意向锁显示为 X,GAP

死锁示例 ​

sql
-- 事务 A
BEGIN;
SELECT * FROM users WHERE id = 5 FOR UPDATE;  -- 间隙锁 (1, 5) 和 (5, 10)

-- 事务 B
BEGIN;
SELECT * FROM users WHERE id = 10 FOR UPDATE;  -- 间隙锁 (5, 10) 和 (10, +∞)

-- 事务 A
INSERT INTO users VALUES (7, 'john');  -- 尝试在 (5, 10) 插入,被事务 B 阻塞

-- 事务 B
INSERT INTO users VALUES (3, 'jane');  -- 尝试在 (1, 5) 插入,被事务 A 阻塞
-- 💥 死锁!InnoDB 会检测并终止其中一个事务

🎯 最佳实践 ​

✅ 推荐做法 ​

1. 固定插入顺序 ​

sql
-- ✅ 按主键顺序插入,减少死锁
INSERT INTO users VALUES (1, 'user1');
INSERT INTO users VALUES (2, 'user2');
INSERT INTO users VALUES (3, 'user3');

2. 批量插入优化 ​

sql
-- ✅ 批量插入,减少锁竞争
INSERT INTO users VALUES 
    (1, 'user1'), (2, 'user2'), (3, 'user3');

❌ 避免陷阱 ​

1. 避免随机插入导致死锁 ​

sql
-- ❌ 危险:多个事务随机插入同一范围
-- 事务 A: INSERT INTO users VALUES (3, ...);
-- 事务 B: INSERT INTO users VALUES (4, ...);
-- 如果有间隙锁,可能死锁

🚨 常见问题 ​

Q1: 插入意向锁会阻塞其他插入吗? ​

答: 不会。多个插入意向锁互相兼容,只在与间隙锁冲突时才阻塞。


Q2: 如何避免插入意向锁导致的死锁? ​

答:

  1. 按顺序插入
  2. 批量插入
  3. 缩短事务时间
  4. 设置超时

📚 相关资源 ​

内部链接 ​

外部资源 ​


最后更新: 2026-04-12
维护状态: ✅ 完整

Released under MIT License.