06_临键锁

临键锁(Next-Key Lock)

简介

在 MySQL 的 InnoDB 存储引擎中,临键锁实际上是两种锁的结合:记录锁和间隙锁。记录锁是在数据行的索引记录上直接加锁,而间隙锁则锁定索引记录之间的间隙。因此,临键锁锁定的是一个索引记录以及该记录之前的间隙。

临键锁通过锁定索引记录以及紧邻索引记录之间的间隙(gap),这样即使是范围查询,也能够确保事务的一致性,防止其他事务对这些范围内的数据进行插入、更新或删除操作。

临键锁用于解决幻读现象,确保事务的隔离级别达到可重复读(REPEATABLE READ)。

临键锁锁定的也是范围,锁定的范围是左开又闭的(a,b]。


原理

临键锁的原理是结合行锁(记录锁)和间隙锁,通过锁定每个索引记录以及前后的间隙,确保在当前事务执行过程中,其他事务不能对这些锁定的范围进行修改,从而避免了幻读现象。

例如,如果一个事务对索引列值为10的记录加了临键锁,它将锁定从上一个索引值到10的间隙以及索引值为10的记录本身。(注意:间隙锁是不会锁定索引值为 10 的)


加锁流程
  1. 开始事务:启动一个事务。
  2. 执行范围查询:对特定的索引范围执行查询。
  3. 加临键锁:InnoDB 在查询范围内的每个索引记录及其前后的间隙上加临键锁。
  4. 执行操作:在持有临键锁的情况下执行查询或修改操作。
  5. 释放锁:事务提交或回滚时,释放临键锁。

临键锁的优缺点

优点

  1. 数据一致性:临键锁通过锁定数据范围和具体行,保持数据在事务中的一致性,避免了幻读。
  2. 隔离性强:在可重复读隔离级别下,临键锁提供了非常强的数据隔离保护,使得事务可以在一个一致的数据视图中操作。

缺点

  1. 性能影响:临键锁可能会锁定大量的数据范围,导致数据库性能下降,尤其是在处理大量范围查询时。
  2. 死锁风险:由于锁定了较大的数据范围,临键锁增加了事务之间发生死锁的可能性。

使用场景

临键锁主要在以下场景中使用:

  • 范围查询:当执行范围查询时,InnoDB 会在查询范围内的每个索引记录及其前后的间隙上加临键锁。例如,SELECT * FROM table WHERE id BETWEEN 10 AND 20 FOR UPDATE
  • 唯一性检查:在插入新记录时,InnoDB 需要检查唯一性约束,可能会在唯一性检查过程中加临键锁,以防止其他事务插入可能导致唯一性冲突的新记录。

示例

假设有一个表 example,包含以下数据:

CREATE TABLE example (
    id INT PRIMARY KEY,
    value VARCHAR(50)
);
INSERT INTO example (id, value) VALUES (5, 'A'), (10, 'B'), (15, 'C');
  1. 事务 A
START TRANSACTION;
-- 对 id 在 10 到 20 之间的记录及其前后的间隙加临键锁
SELECT * FROM example WHERE id BETWEEN 10 AND 20 FOR UPDATE;
  1. 事务 B
START TRANSACTION;
-- 尝试插入 id = 12 的记录,会被阻塞
INSERT INTO example (id, value) VALUES (12, 'D');

在这个示例中:

  • 事务 A 对 id 在 10 到 20 之间的记录及其前后的间隙加了临键锁。
  • 事务 B 尝试在该范围内插入新的记录 id = 12,但由于临键锁的存在,事务 B 的插入操作会被阻塞,直到事务 A 提交或回滚。

锁的兼容性矩阵

为了更好地理解锁的兼容性,以下是锁的兼容性矩阵:

锁类型ISIXSX
ISYesYesYesNo
IXYesYesNoNo
SYesNoYesNo
XNoNoNoNo

临键锁与其他锁的对比
锁类型锁定粒度作用范围使用场景并发性能
表锁表级别整个表DDL 操作、大批量更新
行锁行级别特定行(索引记录)高并发读写
间隙锁行级别(间隙)索引记录之间的间隙防止幻读、范围查询、唯一性检查
临键锁行级别(记录+间隙)索引记录及其前后的间隙防止幻读、范围查询
插入意向锁行级别索引记录之间的间隙高并发插入

总结

间隙锁是 MySQL InnoDB 存储引擎用于防止幻读现象的一种行级锁,通过锁定索引记录之间的间隙,确保在事务执行过程中数据的一致性。它主要用于范围查询和唯一性检查等场景,通过与行锁和意向锁配合,提供细粒度的并发控制和数据保护机制。在设计高并发系统时,理解和正确使用间隙锁有助于提升系统的性能和可靠性。

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值