SQL极简教程 · MySQL · MyBatis · JPA 技术笔记 教程 总结JavaMySQL

MySQL间隙锁、Next-Key Lock主要知识点

2020-03-20  本文已影响0人  白花蛇草可乐

总体来说,就是MySQL innoDB引擎要在RR隔离级别之下解决幻读的问题,所以引入了间隙锁。

在进行当前读的情况下,对读出的数据的附近的一整个范围(“间隙”)进行加锁,保证满足查询条件的记录不能被插入。

1、幻读与innoDB的隔离级别(为什么会出现间隙锁这个概念)

根据 ISO/ANSI SQL92 所定义的标准,四级隔离级别中,只有在可串行化的级别之下,才可以防止幻读的出现。

隔离级别

所谓幻读,指的是事务A执行过程中,由于事务B并发插入了一条新数据,事务A两次读数据的内容不一样,出现了“虚幻”的新纪录(phantom,幽灵)。

但实际上各厂商的数据库产品并没有严格遵守SQL92标准,比如Oracle只有 RC 和 Serializable 两级隔离级别。

MySQL的innoDB引擎虽然拥有标准的四级隔离级别(其实也是MVCC等手段模拟出来的),不过它有一点显著的不同,就是在 RR 级别下面已经可以防止幻读的发生。

下面主要说明跟间隙锁相关的当前读。

2、innoDB的间隙锁/Next-Key Lock

2-1、明确前提条件

所以希望禁用间隙锁,提升系统性能的时候,可以考虑将隔离级别降为 RC。

2-2、间隙锁/Next-Key Lock

间隙锁在innoDB中的唯一作用就是在一定的“间隙”内防止其他事务的插入操作,以此防止幻读的发生:

innoDB支持三种行锁定方式:

innoDB默认的隔离级别是可重复读(Repeatable Read),并且会以Next-Key Lock的方式对数据行进行加锁。Next-Key Lock是行锁和间隙锁的组合,当InnoDB扫描索引记录的时候,会首先对索引记录加上行锁(Record Lock),再对索引记录两边的间隙加上间隙锁(Gap Lock)。加上间隙锁之后,其他事务就不能在这个间隙修改或者插入记录。

当查询的索引含有唯一属性(唯一索引,主键索引)时,Innodb存储引擎会对next-key lock进行优化,将其降为record lock,即仅锁住索引本身,而不是范围。

2-3、何时使用行锁,何时产生间隙锁

对上一节的最后一句做个扩展说明。

  1. 只使用唯一索引查询,并且只锁定一条记录时,innoDB会使用行锁。
  2. 只使用唯一索引查询,但是检索条件是范围检索,或者是唯一检索然而检索结果不存在(试图锁住不存在的数据)时,会产生 Next-Key Lock。
  3. 使用普通索引检索时,不管是何种查询,只要加锁,都会产生间隙锁。
  4. 同时使用唯一索引和普通索引时,由于数据行是优先根据普通索引排序,再根据唯一索引排序,所以也会产生间隙锁。
上一篇 下一篇

猜你喜欢

热点阅读