讲师中心 微信公众号
AI工具推荐 视频效率加速

为什么MySQL默认可重复读隔离级别能解决不可重复读

浅辰大大_6991

浅辰大大_6991

发布时间:2026-09-28 11:06:19

|

570人浏览过

|

来源于php中文网

原创

MySQL可重复读通过MVCC和事务启动时生成的固定Read View确保同一行多次查询结果一致:快照读始终基于该视图从undo log版本链中查找事务开始时已提交的数据版本,屏蔽并发修改。

为什么mysql默认可重复读隔离级别能解决不可重复读

可重复读如何保证同一行数据多次查询结果一致

MySQL InnoDB 的 REPEATABLE READ 隔离级别能解决不可重复读,核心靠的是 MVCC(多版本并发控制) + 事务启动时固定 Read View。不是靠锁住整张表,也不是靠每次都查最新数据,而是让事务“活在自己的快照里”。

关键点在于:事务第一次执行普通 SELECT(即快照读)时,InnoDB 就会生成一个 Read View,它记录了当前活跃事务 ID 列表、最小未分配事务 ID(min_trx_id)、最大已提交事务 ID(max_trx_id)等信息。此后该事务内所有快照读都复用这个视图,只返回满足可见性规则的版本——也就是“对它可见的、且在它开始前已提交”的数据版本。

  • 如果事务 B 在事务 A 启动后修改并提交了某行,B 的事务 ID 一定 > A 的 max_trx_id,所以 A 的 Read View 会忽略这个新版本
  • 即使 B 的修改已落盘、binlog 已写入、从库已同步,A 仍看不到——这不是延迟,是设计上的“一致性快照”
  • 这种机制天然屏蔽了其他事务对“已有行”的 UPDATE 或 DELETE,因此不可重复读(同一行两次查出不同值)被彻底避免

为什么不是靠行锁挡住更新

很多人误以为 REPEATABLE READ 是靠加锁防止别人改,其实不然。普通 SELECT 不加任何锁,是纯无锁读。真正加锁的是 SELECT ... FOR UPDATE、UPDATE、DELETE 这些当前读操作。

也就是说:SELECT * FROM user WHERE id = 1; 不会阻塞别人更新 id=1 的行;但如果你执行 SELECT * FROM user WHERE id = 1 FOR UPDATE;,那就会对这行加记录锁,别人就得等。

  • 快照读不依赖锁,所以并发性能高,也不存在因锁等待导致的响应毛刺
  • 但这也意味着:你读不到别人刚提交的更新,不是数据库“慢”,而是它故意不给你看
  • 如果你需要看到最新值,就必须显式使用当前读,或接受 READ COMMITTED 隔离级别

常见误解:UPDATE 后再 SELECT 看到新值,是不是破坏了可重复读

不会。比如事务 A 执行:

MySQL
MySQL

编写正确的MySQL查询,避免字符集、索引和锁方面的常见陷阱。

下载
SELECT * FROM t WHERE id = 1; -- 返回 name='Alice'
UPDATE t SET name='Bob' WHERE id = 1;
SELECT * FROM t WHERE id = 1; -- 返回 name='Bob'

第二次 SELECT 看到新值,不是因为隔离级别失效,而是因为 UPDATE 是当前读,它会读最新版本并加锁;紧接着的 SELECT 很可能复用了这次更新后的最新行缓存(或触发隐式当前读),并不走原始 Read View。这不是违反可重复读,而是“写后读”场景下自然的行为。

  • 可重复读约束的是“纯读事务”中多次快照读的一致性,不承诺写操作之后的读仍走旧快照
  • 如果你在 UPDATE 后还想验证旧快照,得显式用 SELECT ... LOCK IN SHARE MODE 或另起事务
  • 实际业务中,这类混合读写逻辑必须明确区分快照读和当前读意图,否则容易出现预期外的数据可见性

唯一要注意的边界:快照读 vs 当前读混用时的“不一致感”

最易被忽略的点是:同一个事务内,快照读和当前读共存时,你会“同时生活在两个世界”。例如:

  • 先 SELECT * FROM t WHERE id = 5;(没结果,快照读)
  • 别人插入 id=5 并提交
  • 你再 UPDATE t SET x=1 WHERE id = 5;(成功,当前读看到新行)
  • 再 SELECT * FROM t WHERE id = 5;(看到新行)

这看起来像“幻读”,但它本质是快照读和当前读语义切换导致的认知偏差。InnoDB 没有错,是你没意识到自己主动跳出了快照。

真正要警惕的,不是“能不能解决不可重复读”,而是“有没有混淆读类型”。一旦业务逻辑依赖“读到的数据一定能被后续更新影响”,就必须统一使用当前读,或提前加锁,不能默认靠快照读兜底。

热门AI工具

更多
二狗PPT
二狗PPT Hot

一款AI演示文稿工具,主要用于专为中式职场打造的AI PPT生成工具,适合需要提升相关任务效率的用户。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

相关专题

更多
数据分析工具有哪些
数据分析工具有哪些

数据分析工具有Excel、SQL、Python、R、Tableau、Power BI、SAS、SPSS和MATLAB等。详细介绍:1、Excel,具有强大的计算和数据处理功能;2、SQL,可以进行数据查询、过滤、排序、聚合等操作;3、Python,拥有丰富的数据分析库;4、R,拥有丰富的统计分析库和图形库;5、Tableau,提供了直观易用的用户界面等等。

3863

2023.10.12

SQL中distinct的用法
SQL中distinct的用法

SQL中distinct的语法是“SELECT DISTINCT column1, column2,...,FROM table_name;”。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

831

2023.10.27

SQL中months_between使用方法
SQL中months_between使用方法

在SQL中,MONTHS_BETWEEN 是一个常见的函数,用于计算两个日期之间的月份差。想了解更多SQL的相关内容,可以阅读本专题下面的文章。

1009

2024.02.23

SQL出现5120错误解决方法
SQL出现5120错误解决方法

SQL Server错误5120是由于没有足够的权限来访问或操作指定的数据库或文件引起的。想了解更多sql错误的相关内容,可以阅读本专题下面的文章。

5681

2024.03.06

sql procedure语法错误解决方法
sql procedure语法错误解决方法

sql procedure语法错误解决办法:1、仔细检查错误消息;2、检查语法规则;3、检查括号和引号;4、检查变量和参数;5、检查关键字和函数;6、逐步调试;7、参考文档和示例。想了解更多语法错误的相关内容,可以阅读本专题下面的文章。

2643

2024.03.06

oracle数据库运行sql方法
oracle数据库运行sql方法

运行sql步骤包括:打开sql plus工具并连接到数据库。在提示符下输入sql语句。按enter键运行该语句。查看结果,错误消息或退出sql plus。想了解更多oracle数据库的相关内容,可以阅读本专题下面的文章。

5660

2024.04.07

sql中where的含义
sql中where的含义

sql中where子句用于从表中过滤数据,它基于指定条件选择特定的行。想了解更多where的相关内容,可以阅读本专题下面的文章。

7481

2024.04.29

sql中删除表的语句是什么
sql中删除表的语句是什么

sql中用于删除表的语句是drop table。语法为drop table table_name;该语句将永久删除指定表的表和数据。想了解更多sql的相关内容,可以阅读本专题下面的文章。

1010

2024.04.29

PixTV AI视频生成与无限画布创作
PixTV AI视频生成与无限画布创作

PixTV专题整理AI视频与视觉内容创作相关功能使用教程,涵盖AI生图、视频生成、无限画布、多模型创作、素材管理、声音音乐及视频剪辑等功能,帮助用户快速掌握PixTV从创意到成片的完整制作方法。

0

2026.09.29

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL vs MySQL
PostgreSQL vs MySQL

共1课时 | 176人学习

使用phpenv集成环境安装极致CMS
使用phpenv集成环境安装极致CMS

共2课时 | 281人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn