• 记录锁:Record Locks
  • 间隙锁:Gap Locks
  • 临键锁:Next-key Locks

临键锁(Next-Key Locks)

定义

当 SQL 执行按照索引进行数据的检索时,查询条件为范围查找(between and、<、>等)并有数据命中,则此时 SQL 语句加上的锁为 Next-key locks,锁住索引的记录 + 区间(左开右闭)。

演示案例

演示之前,先看一下 t2 表的结构和数据内容。

image.png

image.png

临键锁(Next-key Locks):InnoDB 默认的行锁算法。

image.png

t2 表中的数据行有4条数据:1,4,7,10,InnoDB 引擎会将表中的数据划分为:(-∞, 1] (1, 4] (4, 7] (7, 10] (10, +∞),执行如下 SQL 语句:

  1. -- 临键锁
  2. -- 事务A执行
  3. BEGIN;
  4. SELECT * FROM t2 WHERE id>5 AND id<9 FOR UPDATE;
  5. ROLLBACK
  6. -- 事务B执行
  7. BEGIN;
  8. SELECT * FROM t2 WHERE id=4 FOR UPDATE; -- 可以执行
  9. SELECT * FROM t2 WHERE id=7 FOR UPDATE; -- 锁住
  10. SELECT * FROM t2 WHERE id=10 FOR UPDATE; -- 锁住
  11. INSERT INTO `t2` (`id`, `name`) VALUES (9, '9'); -- 锁住

image.png

SELECT * FROM t2 WHERE id>5 AND id<9 FOR UPDATE; 这条查询语句命中了7这条数据,它会锁住 (4, 7] 这个区间,同时还会锁住下一个区间 (7, 10]。

为什么 InnoDB 选择临键锁作为行锁的默认算法?

防止幻读。当我们把下一个区间也锁住的时候,这个时候我们要新增数据,就会被锁住,这样就可以防止幻读。

间隙锁(Gap Locks)

定义

当 SQL 执行按照索引进行数据的检索时,查询条件的数据不存在,这时 SQL 语句加上的锁即为 Gap locks,锁住数据不存在的区间(左开右开)
Gap 只在 RR 事务隔离级别存在。因为幻读问题是在 RR 事务通过临键锁和 MVCC 解决的,而临键锁=间隙锁+记录锁,所以间隙锁只在 RR 事务隔离级别存在。

演示案例

image.png

  1. -- 间隙锁
  2. -- 事务A执行
  3. BEGIN;
  4. SELECT * FROM t2 WHERE id>4 AND id <6 FOR UPDATE;
  5. -- 或者
  6. SELECT * FROM t2 WHERE id=6 FOR UPDATE;
  7. ROLLBACK;
  8. -- 事务B执行
  9. INSERT INTO `t2` (`id`, `name`) VALUES (5, '5');
  10. INSERT INTO `t2` (`id`, `name`) VALUES (6, '6');

image.png

SELECT * FROM t2 WHERE id>4 AND id <6 FOR UPDATE; 这条查询语句不能命中数据,它会锁住 (4, 7] 这个区间。

记录锁(Record Locks)

定义

当 SQL 执行按照唯一性(Primary key、Unique key)索引进行数据的检索时,查询条件等值匹配且查询的数据是存在,这时 SQL 语句加上的锁即为记录锁 Record Locks,锁住具体的索引项

演示案例

image.png

  1. -- 记录锁
  2. -- 事务A执行
  3. BEGIN;
  4. SELECT * FROM t2 WHERE id=4 FOR UPDATE;
  5. ROLLBACK;
  6. -- 事务B执行
  7. SELECT * FROM t2 WHERE id=7 FOR UPDATE;
  8. SELECT * FROM t2 WHERE id=4 FOR UPDATE;

image.png

事务A执行 SELECT * FROM t2 WHERE id=4 FOR UPDATE; 把 id=4 的数据行锁住。

当 SQL 执行按照普通索引进行数据的检索时,查询条件等值匹配且查询的数据是存在,这时 SQL 语句锁住数据存在区间(左开右开)

作者:殷建卫 链接:https://www.yuque.com/yinjianwei/vyrvkf/maliph 来源:殷建卫 - 架构笔记 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。