mysql 锁定读和非锁定读

发布时间:2026/9/28 1:23:47

mysql 锁定读和非锁定读
在 MySQL特别是 InnoDB 引擎中‌锁定读Locking Read‌和‌非锁定读Non-Locking Read‌是处理并发事务时两种截然不同的读取策略。它们的核心区别在于读取数据时是否会对行或索引加锁从而影响其他事务的写入操作。一、非锁定读Non-Locking Read这是 MySQL ‌默认‌的读取行为也是大多数 SELECT 语句的执行方式。1. 核心机制MVCC非锁定读依赖于 ‌多版本并发控制MVCC, Multi-Version Concurrency Control‌。当事务执行普通 SELECT 时InnoDB 不会给数据行加任何锁。它通过读取数据的‌历史版本快照Snapshot‌来保证一致性。具体读取哪个版本取决于当前的事务隔离级别‌读已提交RC‌读取该行最新已提交的版本。‌可重复读RR‌读取事务启动时刻生成的快照版本。2. 特点‌高并发‌读操作不会阻塞写操作写操作也不会阻塞读操作除非涉及DDL等元数据锁。‌无等待‌不需要等待其他事务释放锁。‌潜在问题‌在 RC 级别下可能出现“不可重复读”在 RR 级别下虽然解决了不可重复读但在特定场景下如范围查询插入新数据仍可能遇到幻读尽管 InnoDB 通过 Next-Key Lock 尽量规避但普通 SELECT 本身不加锁无法阻止其他事务插入新行只是自身看不到而已。3. 适用场景绝大多数业务查询场景。对数据实时性要求不高或者能容忍短暂不一致的场景。高并发读取场景。二、锁定读Locking Read锁定读是指显式地在 SELECT 语句中加入锁提示强制数据库在读取数据时获取锁从而阻塞其他事务的修改或读取。1. 两种主要类型语法锁类型作用阻塞情况SELECT … FOR SHARE (MySQL 8.0) LOCK IN SHARE MODE (旧版)‌共享锁 (S锁)‌允许其他事务读取该行但‌禁止其他事务修改或删除‌该行。其他事务的写操作会被阻塞直到当前事务提交。SELECT … FOR UPDATE‌排他锁 (X锁)‌‌禁止其他事务读取锁定读、修改或删除‌该行。其他事务的读写操作锁定读都会被阻塞。2. 核心机制锁定读会绕过 MVCC 的快照读取直接读取‌最新已提交的数据‌并立即对该数据行加上相应的锁。如果其他事务已经持有了冲突的锁当前事务会进入‌等待状态‌直到锁释放或超时。3. 适用场景‌数据一致性要求极高‌需要确保在读取后、更新前数据不被其他事务修改。‌业务逻辑依赖当前值‌例如“检查库存是否充足若充足则扣减”必须使用 FOR UPDATE 防止超卖。‌外键约束检查‌InnoDB 在检查外键约束时会自动对引用的父表行加共享锁。‌去重插入‌在插入前先查询是否存在若存在则更新需加锁防止并发插入重复数据。三、对比总结维度非锁定读 (普通 SELECT)锁定读 (FOR SHARE / FOR UPDATE)‌是否加锁‌否是 (S锁或X锁)‌底层技术‌MVCC (快照读)当前读 (Current Read) 锁机制‌并发性能‌高读写互不阻塞低存在锁竞争和等待‌数据实时性‌可能读到旧版本 (取决于隔离级别)总是读到最新已提交数据‌阻塞其他事务‌不阻塞阻塞其他事务的写 (S/X) 或读写 (X)‌典型用途‌日常查询、报表统计转账、扣库存、唯一性校验四、实战示例1. 非锁定读默认--事务ASTARTTRANSACTION;SELECTbalanceFROMaccountsWHEREid1;--此时事务B可以修改 id1的 balance事务A不受影响且看到的是快照数据COMMIT;2. 锁定读排他锁--事务ASTARTTRANSACTION;SELECTbalanceFROMaccountsWHEREid1FORUPDATE;--此时事务B如果想执行UPDATEaccountsSETbalance...WHEREid1;--或者SELECT...FORUPDATE事务B会被阻塞直到事务A提交或回滚UPDATEaccountsSETbalancebalance-100WHEREid1;COMMIT;3举例说明1、场景设定假设有一张商品表 products其中 id1 的商品库存 stock 为 ‌10‌。‌事务 A‌查询库存并准备扣减。‌事务 B‌试图修改同一商品的库存。2、非锁定读示例普通 SELECT2.1执行流程时间事务 A (隔离级别 RR)事务 B状态说明T1START TRANSACTION;事务 A 开启T2SELECT stock FROM products WHERE id1;‌非锁定读‌读取快照不加锁T3UPDATE products SET stock5 WHERE id1;‌成功‌因为 A 没加锁B 可以直接修改并提交T4COMMIT;事务 B 提交库存变为 5T5SELECT stock FROM products WHERE id1;‌仍返回 10‌RR 级别下A 看到的是 T1 时刻的快照T6UPDATE products SET stockstock-1 WHERE id1;‌成功‌A 基于快照值 10 计算最终库存变为 92.2. 结果分析‌问题‌发生了‌丢失更新‌。事务 B 将库存改为 5但事务 A unaware基于旧值 10 扣减后变成 9导致 B 的修改被覆盖。‌特点‌读写互不阻塞并发高但数据一致性需应用层保证如乐观锁。3、锁定读示例SELECT … FOR UPDATE3.1. 执行流程时间事务 A (隔离级别 RR)事务 B状态说明T1START TRANSACTION;事务 A 开启T2SELECT stock FROM products WHERE id1 FOR UPDATE;‌锁定读‌读取最新值 10并加‌排他锁 (X锁)‌T3UPDATE products SET stock5 WHERE id1;‌阻塞‌B 试图获取 X 锁但被 A 持有进入等待T4UPDATE products SET stockstock-1 WHERE id1;‌成功‌A 基于当前值 10 扣减库存变为 9T5COMMIT;事务 A 提交释放锁T6(解除阻塞) UPDATE … 执行‌成功‌B 获取锁基于 A 提交后的值 9 继续操作3.2. 结果分析‌优势‌保证了‌串行化效果‌。事务 B 必须等待 A 完成确保了 A 读取和写入期间数据不被干扰。‌特点‌数据强一致但并发性能低存在锁等待风险。4、核心区别总结维度非锁定读 (Snapshot Read)锁定读 (Current Read)‌SQL 语句‌SELECT …SELECT … FOR UPDATE / FOR SHARE‌是否加锁‌‌否‌依赖 MVCC 快照‌是‌直接对索引行加锁‌读取内容‌历史版本快照 (可能非最新)数据库最新已提交数据‌并发影响‌不阻塞其他事务的写操作阻塞其他事务的写 (或读) 操作‌典型后果‌可能出现不可重复读或丢失更新确保数据在读写期间的一致性‌适用建议‌大多数查询场景涉及资金、库存等关键资源的读写序列5、避坑指南‌索引必须命中‌如果 SELECT … FOR UPDATE 没有走索引如 WHERE name‘xxx’ 且无索引InnoDB 会退化为‌全表锁‌导致整个表无法被其他事务修改严重拖垮系统。‌死锁预防‌多个事务以不同顺序锁定多行数据时极易死锁。建议业务层固定加锁顺序或设置合理的超时时间。‌RR 级别的间隙锁‌在可重复读级别下锁定读不仅锁住行还可能锁定‌间隙‌即防止其他事务插入新数据这在处理范围查询时需特别注意可能意外阻塞正常的插入操作五、注意事项‌死锁风险‌锁定读容易引发死锁。例如事务 A 锁定了行 1 等待行 2事务 B 锁定了行 2 等待行 1。务必保持加锁顺序一致或设置合理的 innodb_lock_wait_timeout。‌索引的重要性‌锁定读必须通过‌索引‌来定位行。如果查询没有走索引全表扫描InnoDB 可能会锁定整个表的所有行或大量间隙锁导致严重的性能下降甚至系统瘫痪。‌隔离级别影响‌在 ‌RC‌ 级别下FOR UPDATE 只锁住满足条件的行。在 ‌RR‌ 级别下FOR UPDATE 除了锁住行还可能加上‌间隙锁Gap Lock‌或‌Next-Key Lock‌以防止幻读。这意味着即使某些行不存在也可能被锁定导致其他事务无法插入这些数据。‌MySQL 8.0 变化‌推荐使用 FOR SHARE 替代旧的 LOCK IN SHARE MODE语义更清晰且符合 SQL 标准。

相关新闻

Arduino驱动LCD屏幕实现图片显示的完整指南

Arduino驱动LCD屏幕实现图片显示的完整指南

2026/8/23 0:01:28

1. Arduino与LCD显示基础在嵌入式开发领域,Arduino因其易用性和丰富的生态系统成为入门首选。当我们需要在项目中实现可视化交互时,LCD屏幕是最常见的选择之一。不同于简单的文本显示,图片显示对硬件和软件都有更高要求。典型的Arduino LCD图…

AI标准化审查系统:提升机械图纸审查效率300%

AI标准化审查系统:提升机械图纸审查效率300%

2026/9/9 21:02:49

1. 项目背景:标准化审查的困境与AI机遇在机械制造、建筑工程、电子设计等行业,标准化审查是产品开发流程中不可或缺的环节。作为从业15年的机械设计工程师,我亲眼见证过标准化审查员每天面对堆积如山的图纸时那种力不从心的状态。传统模式下&…

Claude模型合规使用指南:从原理到实践的完整解决方案

Claude模型合规使用指南:从原理到实践的完整解决方案

2026/9/8 23:11:28

如果你正在寻找最新的AI大模型使用方案,可能会发现一个奇怪的现象:网上充斥着各种"GPT5.6"、"Gemini3.5"、"Claude满血版"的教程,但真正能跑通的却寥寥无几。这背后反映的是国内开发者面临的实际困境&#xff…

CANN/GE ACL数据集缓冲区添加函数

CANN/GE ACL数据集缓冲区添加函数

2026/9/26 19:14:12

aclmdlAddDatasetBuffer 【免费下载链接】ge GE(Graph Engine)是面向昇腾的图编译器和执行器,提供了计算图优化、多流并行、内存复用和模型下沉等技术手段,加速模型执行效率,减少模型内存占用。 GE 提供对 PyTorch、Te…

用ffmpeg高效批量调整图片尺寸的实战指南

用ffmpeg高效批量调整图片尺寸的实战指南

2026/9/27 1:30:29

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱

2026/9/27 1:30:37

Transformers 音频特征提取工具库 audio_utils 全解析:从 Mel 刻度换算到对数 Mel 频谱 【免费下载链接】transformers 🤗 Transformers: the model-definition framework for state-of-the-art machine learning models in text, vision, audio, and mu…

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南

2026/9/27 1:30:35

RustFS 多节点集群重启与滚动升级实战:Readiness、Quorum 与 Degraded 模式完全指南 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system sup…

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

Java Integer缓存揭秘:128陷阱原理、避坑与面试全解

2026/9/27 1:30:34

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据

2026/9/26 16:36:51

RustFS Scanner 数据用量发布权威性决策:配额准入如何获得可用的权威依据 【免费下载链接】rustfs 🚀2.3x faster than MinIO for 4KB object payloads. RustFS is an open-source, S3-compatible high-performance object storage system supporting mi…

远程协作的工作台整理

远程协作的工作台整理

2026/9/26 14:29:04

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/26 13:57:22

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/26 23:35:16

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…