间隙锁

3次阅读
没有评论

 

没关系,这部分确实是 MySQL 中最抽象的概念。咱们换个方式,不用专业术语,用**“停车位”**的例子来类比,你一秒钟就能懂。

假设有一排停车位,编号分别是 1、5、10(对应数据库里 ID 为 1, 5, 10 的三行记录)。


1. Record Lock(记录锁):精准锁住“车位”

动作:你直接锁定了 5 号车位。

  • 效果:别人不能停在 5 号位,也不能改 5 号位的信息。

  • 范围:仅仅是 ID = 5 这一行。

  • 场景:当你执行 UPDATE users SET name='xxx' WHERE id = 5; 时,MySQL 就会加这个锁。


2. Gap Lock(间隙锁):锁住车位间的“空地”

动作:你锁住了 1 号到 5 号之间的空地,以及 5 号到 10 号之间的空地。

  • 效果:别人不能在 1 和 5 之间插入新的车位(比如 ID=2, 3, 4)。

  • 重点:它不锁 1 和 5 本身,只锁它们中间的间隙。

  • 目的防止幻读。如果你不锁间隙,别人在你查询期间插了一条 ID=3 的数据,你再次查询就会发现多了一行,像见鬼(幻觉)一样。


3. Next-Key Lock(临键锁):车位 + 左侧空地(全包)

动作:这是 InnoDB 的默认大招,它是记录锁 + 间隙锁的合体。

  • 算法:它锁住的是一个左开右闭的区间。比如 (1, 5]

  • 范围:它锁住了 1 到 5 之间的空地并且锁住了 5 号车位本身

  • 效果

    • 别人不能插入 ID=2, 3, 4(间隙锁生效)。

    • 别人也不能修改或删除 ID=5(记录锁生效)。

    • 但 ID=1 是不受影响的。


📝 为什么面试官总考这个?(核心痛点)

为了让你彻底理解,看这个操作场景:

背景:表里有 ID=1, 5, 10。

操作:事务 A 执行 SELECT * FROM users WHERE id > 5 AND id < 10 FOR UPDATE;

  1. 如果不加锁:事务 B 插入了 ID=7。事务 A 再次查,发现多了一个 7,这就是幻读

  2. 只加记录锁:事务 A 发现 ID=5 和 ID=10 没变,但中间多出来个 7,还是防不住。

  3. 加了 Next-Key Lock:它会把 (5, 10] 这个区间全部封死。事务 B 想 INSERT INTO ... VALUES (7)?对不起,阻塞等待


总结一下

  • Record Lock:别动我的现成数据

  • Gap Lock:别往我两行中间插新数据

  • Next-Key Lock:既别动我的现成数据,也别往我这插新数据(最稳,但并发性能稍微降低)。

现在这三个“锁”的形象是不是清晰多了?需要我再给你举个例子,演示一下在什么奇怪的操作下会导致“死锁”吗?(比如两个事务交叉锁间隙)

正文完
 0
bdspAdmin
版权声明:本站原创文章,由 bdspAdmin 于2026-03-25发表,共计988字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
评论(没有评论)