MySQL间隙锁入手,拿下间隙锁面试与实操

news2025/6/9 22:07:17

一、MySQL 间隙锁,究竟是什么?

在 MySQL 的世界里,间隙锁(Gap Lock)就像是一个默默守护数据一致性的卫士,看似低调,却在并发控制中扮演着至关重要的角色。​

想象一下,你去图书馆借书,书架上的书按照编号依次排列。你想要借编号在 10 - 20 之间的书,这时候图书馆管理员为了保证你借到的书是符合你要求的,他不仅会把编号 10 - 20 的书标记为已被你预订(就像行锁锁住了具体的数据行),还会把编号 9 和 21 之间的空位也标记起来(这就相当于间隙锁),防止其他人在你借书期间把一本编号为 15 的新书插入到这个空位中,导致你借到的书不符合你原本要求的范围。​

从官方文档的角度来看,间隙锁是 InnoDB 存储引擎在可重复读(Repeatable Read)事务隔离级别下用来防止幻读(Phantom Read)的一种锁机制。当一个事务执行范围查询时,MySQL 会为查询结果集中的每个记录都加上间隙锁,即锁定了记录之间的间隙(Gap)。​
从原理上来说,间隙锁锁定的是索引记录之间的间隙,或者是第一个索引记录之前、最后一个索引记录之后的空间。例如,有一个表中的记录按照某个列的升序排列,事务 A 执行以下查询:

SELECT * FROM table WHERE col BETWEEN 10 AND 20 FOR UPDATE;

MySQL 会为查询结果中的记录加上间隙锁,即锁定了 10 到 20 之间的间隙。这样,其他事务在这个范围内插入新记录时会被阻塞,直到事务 A 提交或者回滚。需要注意的是,间隙锁只在使用索引的情况下生效。如果查询条件没有使用索引,MySQL 不会使用间隙锁 。​

间隙锁的作用主要是防止幻读。幻读指的是在一个事务中,多次执行相同的查询,由于其他事务的插入或删除操作,导致每次查询的结果集不一样,就好像出现了幻觉一样。间隙锁通过锁定记录之间的间隙,阻止其他事务在这个间隙中插入新记录,从而保证了在一个事务中多次执行相同的范围查询时,结果集的一致性。

二、间隙锁的使用场景与实战演练

2.1 实际应用场景​

在实际应用中,间隙锁在许多场景下都发挥着重要作用。比如在电商系统的订单模块中,当查询某个时间段内的订单列表时,为了保证在查询过程中不会有新的订单插入到这个时间段内,从而影响查询结果的一致性,就可以使用间隙锁。又比如在库存管理系统中,当查询某个库存数量范围的商品时,间隙锁可以防止其他事务在这个范围内插入或修改商品库存记录,确保库存数据的准确性 。

2.2 建表示例与加锁分析​

接下来,我们通过一个具体的建表示例来深入了解间隙锁在不同事务隔离级别下的加锁情况。​
首先,创建一个名为products的表,用于存储商品信息,表结构如下:

CREATE TABLE products (
    id INT PRIMARY KEY AUTO_INCREMENT,
    product_name VARCHAR(100) NOT NULL,
    stock INT NOT NULL,
    price DECIMAL(10, 2) NOT NULL
);

插入一些数据:

INSERT INTO products (product_name, stock, price) VALUES
('Product A', 10, 100.00),
('Product B', 20, 200.00),
('Product C', 30, 300.00);
2.2.1 可重复读(Repeatable Read)隔离级别​

在可重复读隔离级别下,我们进行如下操作:

-- 开启事务
START TRANSACTION;
-- 范围查询并加锁
SELECT * FROM products WHERE stock BETWEEN 15 AND 25 FOR UPDATE;

在这个例子中,stock列上有索引(假设我们创建了索引idx_stock),当执行上述查询时,MySQL 会对stock值在 15 到 25 之间的记录加上间隙锁,同时对符合条件的记录加上记录锁(如果有记录满足条件)。具体来说,会锁定stock值为 10 和 20 之间的间隙,以及 20 和 30 之间的间隙,防止其他事务在这些间隙中插入新的记录。​

2.2.2 读已提交(Read Committed)隔离级别​

将事务隔离级别设置为读已提交:

SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 开启事务
START TRANSACTION;
-- 范围查询并加锁
SELECT * FROM products WHERE stock BETWEEN 15 AND 25 FOR UPDATE;

在读已提交隔离级别下,MySQL 不会使用间隙锁,只会对符合条件的记录加上记录锁。也就是说,只会锁定stock值为 20 这条记录(如果存在满足条件的记录),而不会锁定记录之间的间隙,其他事务可以在间隙中插入新的记录 。​

2.2.3 插入操作​

在可重复读隔离级别下,当执行插入操作时,如果插入的值落在间隙锁的范围内,会被阻塞。例如:

-- 事务A
START TRANSACTION;
SELECT * FROM products WHERE stock BETWEEN 15 AND 25 FOR UPDATE;
-- 事务B
START TRANSACTION;
INSERT INTO products (product_name, stock, price) VALUES ('New Product', 22, 220.00); -- 会被阻塞

在这个例子中,事务 A 对stock在 15 到 25 之间的范围加了间隙锁,事务 B 试图插入stock值为 22 的记录,由于该值落在间隙锁的范围内,所以事务 B 的插入操作会被阻塞,直到事务 A 提交或回滚 。​

2.2.4 更新操作​

同样在可重复读隔离级别下,更新操作如果涉及到间隙锁范围内的记录,也会受到影响。例如:

-- 事务A
START TRANSACTION;
SELECT * FROM products WHERE stock BETWEEN 15 AND 25 FOR UPDATE;
-- 事务B
START TRANSACTION;
UPDATE products SET stock = 22 WHERE product_name = 'Product B'; -- 会被阻塞

事务 A 对stock在 15 到 25 之间的范围加了间隙锁,事务 B 试图更新Product B的stock值为 22,由于更新后的值落在间隙锁的范围内,所以事务 B 的更新操作会被阻塞 。​

三、解锁面试:巧妙回答间隙锁问题​

在面试中,当被问到关于 MySQL 间隙锁的问题时,面试官通常希望考察你对数据库并发控制和事务隔离的理解,以及你在实际应用中解决问题的能力。因此,回答时要清晰、有条理,重点突出间隙锁的概念、原理、应用场景以及与其他锁机制的区别 。

3.1 回答思路​

首先,简要介绍间隙锁的基本概念,强调它是 InnoDB 存储引擎在可重复读事务隔离级别下用于防止幻读的一种锁机制。例如:“间隙锁是 InnoDB 在可重复读事务隔离级别下,为了防止幻读而引入的一种锁。它锁定的是索引记录之间的间隙,而不是具体的记录。”​
接着,阐述间隙锁的工作原理,包括锁定的范围和方式。可以结合具体的 SQL 示例进行说明,如:“当执行SELECT * FROM table WHERE col BETWEEN 10 AND 20 FOR UPDATE;这样的范围查询时,MySQL 会对col值在 10 到 20 之间的记录加上间隙锁,同时对符合条件的记录加上记录锁(如果有记录满足条件)。具体来说,会锁定col值为 10 和 20 之间的间隙,以及 20 和 30 之间的间隙,防止其他事务在这些间隙中插入新的记录 。”​
然后,提及间隙锁的应用场景,展示你对其实际用途的理解。比如:“在电商系统的订单模块中,当查询某个时间段内的订单列表时,为了保证在查询过程中不会有新的订单插入到这个时间段内,从而影响查询结果的一致性,就可以使用间隙锁。”​
最后,对比间隙锁与其他锁机制(如记录锁、表锁)的区别,进一步体现你对锁机制的全面掌握。例如:“记录锁锁定的是具体的索引记录,而间隙锁锁定的是索引记录之间的间隙;表锁的粒度较大,会锁定整个表,而间隙锁的粒度较小,只锁定特定的间隙范围 。”​

3.2 示例回答​

“MySQL 的间隙锁是 InnoDB 存储引擎在可重复读事务隔离级别下,为了防止幻读而引入的一种锁机制。简单来说,间隙锁锁定的是索引记录之间的间隙,而不是具体的记录。​
当我们执行一个范围查询时,比如SELECT * FROM products WHERE stock BETWEEN 15 AND 25 FOR UPDATE;,如果stock列上有索引,MySQL 会对stock值在 15 到 25 之间的记录加上间隙锁,同时对符合条件的记录加上记录锁(如果有记录满足条件)。具体而言,它会锁定stock值为 10 和 20 之间的间隙,以及 20 和 30 之间的间隙,这样其他事务就无法在这些间隙中插入新的记录,从而避免了幻读的发生 。​
在实际应用中,间隙锁在很多场景下都非常有用。例如在电商系统的库存管理中,当查询某个库存数量范围的商品时,间隙锁可以防止其他事务在这个范围内插入或修改商品库存记录,确保库存数据的准确性 。​
与其他锁机制相比,记录锁主要锁定的是具体的索引记录,而间隙锁关注的是记录之间的间隙;表锁则是锁定整个表,粒度较大,而间隙锁的粒度相对较小,只针对特定的间隙范围进行锁定 。总的来说,间隙锁在保证数据一致性和防止幻读方面发挥着重要作用,但在使用时也需要注意它可能对并发性能产生的影响 。”​

3.3 补充说明​

在回答完上述内容后,如果还有时间和机会,可以进一步补充一些关于间隙锁的注意事项或优化建议,如:​
间隙锁对性能的影响:间隙锁虽然能有效防止幻读,但由于它会锁定索引记录之间的间隙,可能会导致其他事务在插入新记录时被阻塞,从而影响数据库的并发性能。在高并发场景下,需要特别关注间隙锁的使用,避免出现性能瓶颈 。​
优化建议:为了减少间隙锁对性能的影响,可以尽量使用唯一索引进行查询,因为在唯一索引上使用等值查询时,InnoDB 会使用记录锁而不是间隙锁;合理设计数据库表结构和索引,避免不必要的范围查询;调整事务隔离级别,如果业务对数据一致性要求不是特别高,可以选择读已提交隔离级别,此时 MySQL 不会使用间隙锁 。​

MySQL 间隙锁作为一种在并发控制中防止幻读的重要机制,在数据库事务处理中起着关键作用。它通过锁定索引记录之间的间隙,有效避免了在可重复读事务隔离级别下因其他事务插入新记录而导致的幻读问题 。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2405894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

词法分析和词性标注 自然语言处理

目录 一. 概述 1 不同语言的词法分析 2 英语的形态分析 英语单词的形态还原(和正常英语的词法变化一样) 1.有规律变化单词的形态还原 ​编辑 2.动词、名词、形容词、副词不规则变化单词的形态还原 3.对于表示年代&…

QT聊天项目DAY14

1. 客户端登录 1.1 初始化玩家头像 将头像的大小固定在250 * 250 void InitHeadImage(); // 初始化头像/* 初始化头像 */ void LoginWidget::InitHeadImage() {// 加载头像QPixmap OriginalPixmap(":/Chat/Images/head_5.jpg");OriginalPixmap …

架构设计技巧——架构设计模板

一份实用、高效、覆盖核心要素的架构设计模板是确保设计质量、促进团队沟通和指导实施的关键。以下是一个经过提炼的架构设计文档核心模板框架,结合了业界最佳实践,并强调灵活裁剪: 架构设计文档模板 (核心框架) 文档标识 项目/系统名称&a…

【Ragflow】27.RagflowPlus(v0.4.1):小版本迭代,问题修复与功能优化

概述 RagflowPlus v0.4.0 在发布后,收到了积极的反馈,同时也包含一些问题。 本次进行一轮小版本更新,发布 v0.4.1 版本,对已知问题进行修复,并对部分功能进行进一步优化。 开源地址:https://github.com/…

【Oracle】数据仓库

个人主页:Guiat 归属专栏:Oracle 文章目录 1. 数据仓库概述1.1 为什么需要数据仓库1.2 Oracle数据仓库架构1.3 Oracle数据仓库关键技术 2. 数据仓库建模2.1 维度建模基础2.2 星形模式设计2.3 雪花模式设计2.4 缓慢变化维度(SCD)处…

基于开源AI大模型AI智能名片S2B2C商城小程序源码的中等平台型社交电商运营模式研究

摘要:本文聚焦中等平台型社交电商,探讨其与传统微商及大型社交电商平台的差异,尤其关注产品品类管理对代理运营的影响。通过引入开源AI大模型、AI智能名片与S2B2C商城小程序源码技术,构建智能化运营体系。研究结果表明&#xff0c…

Vite 双引擎架构 —— Esbuild 概念篇

Vite 底层采用 双引擎架构,核心构建引擎是 Esbuild 和 Rollup,二者在开发和生产环境中分工协作,共同实现高性能构建。不可否认,作为 Vite 的双引擎之一,Esbuild 在很多关键的构建阶段(如依赖预编译、TS 语法转译、代码…

阿里云Alibaba Cloud安装Docker与Docker compose【图文教程】

个人记录 进入控制台,找到定时与自动化任务 进入‘安装/卸载扩展程序’ 点击‘安装扩展程序’ 选择docker社区版,点击下一步与确定,等待一会 安装成功 查询版本 查询docker sudo docker version查询docker compose sudo docker compo…

ADB识别手机系统弹授权框-如何处理多重弹框叠加和重叠问题

ADB识别手机系统弹授权框-如何处理多重弹框叠加和重叠问题 --蓝牙电话SDK自动部署 上一篇:手机App-插入USB时自动授权点击确定按钮-使系统弹出框自动消失 下一篇:编写中。 一、前言 我们在上一篇《手机App-插入USB时自动授权点击确定按钮-使系统弹出框…

uniapp+<script setup lang=“ts“>解决有数据与暂无数据切换显示,有数据加载时暂无数据闪现(先加载空数据)问题

声明showEmpty 为false&#xff0c;在接口返回处判断有数据时设置showEmpty 为false&#xff0c;接口返回数据为空则判断showEmpty 为true &#xff08;这样就解决有数据的时候会闪现暂无数据的问题啦&#xff09; <!--* Date: 2024-02-26 03:38:52* LastEditTime: 2025-06…

详解鸿蒙Next仓颉开发语言中的动画

大家上午好&#xff0c;今天来聊一聊仓颉开发语言中的动画开发。 仓颉中的动画通常有两种方式&#xff0c;分别是属性动画和显示动画&#xff0c;我们今天以下面的加载动画为例&#xff0c;使用显示动画和属性动画分别实现一下&#xff0c;看看他们有什么区别。 显示动画 显示…

Redis常见使用场景解析

1. 数据库缓存 Redis 作为典型的 Key-Value 型内存数据库,数据缓存是其最广为人知的应用场景。使用 Redis 缓存数据操作简便,通常将序列化后的对象以 string 类型存储。但在实际应用中,需注意以下关键要点: Key 设计:必须确保不同对象的 Key 具有唯一性,且尽量缩短长度,…

起重机指挥人员在工作中需要注意哪些安全事项?

起重机指挥人员在作业中承担着协调设备运行、保障作业安全的关键职责&#xff0c;其安全操作直接关系到整个起重作业的安全性。以下从作业前、作业中、作业后的全流程&#xff0c;详细说明指挥人员需注意的安全事项&#xff1a; 一、作业前的安全准备 资质与状态检查&#xff…

JAVA-springboot log日志

SpringBoot从入门到精通-第8章 日志的操作 一、Spring Boot默认的日志框架 SpringBoot支持很多种日志框架&#xff0c;通常情况下&#xff0c;这些日志框架都是由一个日志抽象层和一个日志实现层搭建而成的&#xff0c;日志抽象层是为记录日志提供的一套标准且规范的框架&…

1.springmvc基础入门(一)

1.Spring MVC概念 Spring MVC 是 Spring Framework 提供的 Web 组件&#xff0c;全称是 Spring Web MVC&#xff0c;是⽬前主流的实现 MVC 设计模式的框架&#xff0c;提供前端路由映射、视图解析等功能。 Java Web 开发者必须要掌握的技术框架。 2.Spring MVC 功能 MVC&am…

模块缝合-把A模块换成B模块(没写完)

把MLP Head替换为KAN 1.在model文件下新建一个python文件 2.把 模块文件里的整个KAN代码复制到新的python文件中 3.在开头导入 from model.KAN(新建文件名&#xff09; import KAN&#xff08;新建文件中的类名&#xff09; 4.sys.path.append(r"D: Icode(Kansformer"…

从零开始学Flink:揭开实时计算的神秘面纱

一、为什么需要Flink&#xff1f; 当你在电商平台秒杀商品时&#xff0c;1毫秒的延迟可能导致交易失败&#xff1b;当自动驾驶汽车遇到障碍物时&#xff0c;10毫秒的计算延迟可能酿成事故。这些场景揭示了一个残酷事实&#xff1a;数据的价值随时间呈指数级衰减。 传统批处理…

Appium如何支持ios真机测试

ios模拟器上UI自动化测试 以appiumwebdriverio为例&#xff0c;详细介绍如何在模拟器上安装和测试app。在使用ios模拟器前&#xff0c;需要安装xcode&#xff0c;创建和启动一个simulator。simulator创建好后&#xff0c;就可以使用xcrun simctl命令安装被测应用并开始测试了。…

JDK17 Http Request 异步处理 源码刨析

为什么可以异步&#xff1f; #调用起始源码 // 3. 发送异步请求并处理响应 CompletableFuture future client.sendAsync( request, HttpResponse.BodyHandlers.ofString() // 响应体转为字符串 ).thenApply(response -> { // 状态码检查&#xff08;非200系列抛出异常&…

【Zephyr 系列 8】构建完整 BLE 产品架构:状态机 + AT 命令 + 双通道通信实战

🧠关键词:Zephyr、BLE、状态机、双向透传、AT 命令、Buffer、主从共存、系统架构 📌适合人群:希望开发 BLE 产品(模块/标签/终端)具备可控、可测、可维护架构的开发者 🧭 引言:从“点功能”到“系统架构” 前面几篇我们已经逐步构建了 BLE 广播、连接、数据透传系统…