01.27 Day 8 - 间隙锁和 next-key lock

大家好,我是 Snow Hide,作为《MySQL 实战》这个专栏的学员之一,这是我打卡的第 8 天,也是我第 51 次进行这种操作。

今天我温习了该专栏里一篇叫《幻读是什么,幻读有什么问题?》的文章。

关键词总结:幻读是什么?、幻读有什么问题?(语义问题、一致性问题)、如何解决幻读?(间隙锁、next-key lock、Supremum、间隙锁生效场景)。

所学总结:

幻读是什么?

一个事务在前后两次查询同一个范围的时候,后一次查询看到了前一次查询没有看到的行。幻读在 “当前读” 下才会出现。幻读仅指 “新插入的行”。
 

幻读有什么问题?

语义问题

事务一的语句根据某个字段的值的条件查询到了数据,事务二根据另一个值的条件更改将事务一查询时所依赖的字段的值更改成与事务一查询时所匹配的值,导致事务三在执行事务一相通的查询语句时多查出一条数据,这个操作破坏了事务一里查询语句的加锁声明。随后,事务四插入了一条数据,在事务一查询所依赖的字段上插入了与事务一查询条件匹配的值,导致事务四在执行与事务一相同查询语句时查询出新插入的数据,一共查询出三条语句,这也破坏了事务一查询语句的加锁声明。

一致性问题

锁的设计是为了保证数据的一致性。而这个一致性,不止是数据库内部数据状态在此刻的一致性,还包含了数据和日志在逻辑上的一致性。即使把所有的记录都加上锁,还是阻止不了新插入的记录,这也就是为什么 “幻读” 会被单独拿出来解决的原因。
 

如何解决幻读?

间隙锁

为了解决幻读问题,InnoDB 引入了间隙锁(Gap Lock)。
将两个值之间的空隙锁住。数据行是可以加上锁的实体,数据行之间的间隙也可以加上锁的实体。
跟间隙锁存在冲突关系的,是 “往这个间隙中插入一个记录” 这个操作。
间隙锁 = 开区间

next-key lock

开后闭区间。

Supremum

+∞是开区间。InnoDB 给每个索引加了一个不存在的最大值 spuremum,也就是 “前开后闭区间”。

间隙锁生效场景

在可重读隔离级别下才会生效。

末了

重新总结了一下文中提到的内容:全表扫描的加锁方式、解决幻读问题、引入间隙锁、由于间隙锁导致的死锁现象、间隙锁会影响系统的并发度。

发布了103 篇原创文章 · 获赞 6 · 访问量 5078

猜你喜欢

转载自blog.csdn.net/stevenchen1989/article/details/104090818