05_间隙锁

间隙锁(Gap Lock)

简介

在 MySQL 中,间隙锁(Gap Lock)是 InnoDB 存储引擎的一种特殊类型的行级锁,用于防止幻读现象,确保事务的隔离级别达到可重复读(REPEATABLE READ)。

间隙锁主要在范围查询和唯一性检查时使用,它通过锁定索引记录之间的间隙,而不是锁定实际的索引记录或行。

它主要用于聚簇索引和辅助索引,防止其他事务在这些间隙中插入新记录,或者防止多个事务同时插入相同的值,从而避免幻读现象。

间隙锁只锁定范围,不锁定具体的索引记录对应的行数据,即锁定的区间是开区间(a,b)。


原理

在可重复读隔离级别下,InnoDB存储引擎使用多版本并发控制(MVCC)来维护数据的一致性。间隙锁是InnoDB中MVCC机制的一部分,它是通过锁定一个范围内的所有可能间隙,确保在同一事务的执行过程中,该范围内的数据不会发生变化。这样,在事务执行期间,其他事务无法在这些间隙中插入新记录,确保事务的一致性。

例如,如果一个表中有两条记录,其关键字值为10和20,间隙锁可以锁定从10到20之间的间隙,这意味着其他事务不能在这个范围内插入一个新的关键字值(如15)。但是,这些事务仍然可以查询、更新或删除这个范围内现有的记录。

如果是基于唯一索引或主键索引的唯一记录操作,即只操作一条记录,不会加间隙锁。


加锁流程

前提:操作的数据一定是某个范围内的,不能是单独的一条数据。

  1. 开始事务:启动一个事务。
  2. 执行范围查询:对特定的索引范围执行查询。
  3. 加间隙锁:InnoDB 在查询范围内加上间隙锁,锁定范围内的所有间隙,而不是具体的行。
  4. 执行操作:在持有间隙锁的情况下执行查询或修改操作。
  5. 释放锁:事务提交或回滚时,释放间隙锁。

间隙锁的使用场景
  • 范围查询:当执行范围查询时,InnoDB 会在查询范围内加间隙锁,防止其他事务在该范围内插入新记录。例如,SELECT * FROM example WHERE id BETWEEN 10 AND 20 FOR UPDATE
  • 唯一性检查:在插入新记录时,InnoDB 可能会在唯一性检查过程中加间隙锁,以防止其他事务插入可能导致唯一性冲突的新记录。
  • 防止幻读:在事务隔离级别为可重复读(REPEATABLE READ)时,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 提交或回滚。

间隙锁的优点与缺点

优点

  • 防止幻读:间隙锁可以有效地防止幻读现象,即在一个事务内读取到另一个事务新增的记录。
  • 提高并发性:允许多个事务在不同的数据范围内并行操作,提高了系统的并发能力。

缺点

  • 可能导致死锁:间隙锁可能增加死锁的概率,因为它们增加了事务之间锁定资源的复杂性。
  • 性能影响:在某些情况下,间隙锁可能导致不必要的锁定,从而降低数据库的性能。

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

总结

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值