如何理解临键锁Next-Key Lock_行锁与间隙锁的组合原理解析
临键锁锁定的是左开右闭区间如对索引值20加锁即锁住(10,20]包含记录20及前一索引间隙仅作用于被扫描的索引范围且在REPEATABLE READ下启用。临键锁到底锁了哪块数据临键锁不是新锁类型而是 Record Lock行锁和 Gap Lock间隙锁的自动组合只在 REPEATABLE READ 隔离级别下默认启用。它锁定的是一个「左开右闭」区间比如索引值为 10、20、30那么对 20 加临键锁实际锁住的是 (10, 20] —— 包含记录 20 本身也包含它前面那个“空档”。关键点在于这个“前面”是按索引顺序算的不是物理位置且只作用于**被扫描到的索引范围**不是整张表。如果你 SELECT * FROM t WHERE id 20 FOR UPDATE且 id 是主键 → InnoDB 会优化成纯行锁Record Lock不加间隙部分但如果是 SELECT * FROM t WHERE id 15 AND id → 即使只有 id20 一条匹配也会锁住 code(10, 20] 和 (20, 30] 两个临键区间如果查询没走索引比如 WHERE name xxx 且 name 无索引InnoDB 可能退化为全表扫描表级锁临键锁机制完全失效为什么有时 update 会被莫名其妙卡住这是临键锁最典型的副作用你以为只改一行其实锁了一片区域别人往“缝隙里”插数据就被堵住了。常见卡顿场景T1 执行 SELECT * FROM users WHERE age BETWEEN 22 AND 28 FOR UPDATE → 锁住所有 age 在 [22,28] 的记录 它们前后的间隙比如 (20, 22]、(22, 28]、(28, 30]T2 尝试 INSERT INTO users (age, name) VALUES (25, new) → 被阻塞因为 25 落在已锁的 (22, 28] 区间内T3 尝试 INSERT INTO users (age, name) VALUES (21, old) → 同样被阻塞因 21 落在 (20, 22] 内这不是 bug是 InnoDB 主动防止幻读的设计。但业务上若频繁范围查询 并发插入就容易形成隐性锁竞争。 知元AI AI智能语音聊天 对讲问答 AI绘画 AI写作 AI创作助手工具