尧图网站建设 尧图网络
  • 首页
  • 关于我们
  • 服务项目
  • 案例展示
  • 建站流程
  • 资讯中心
  • 联系我们
首页/资讯中心/详情

MySQL 事务隔离级别详解

MySQL 事务隔离级别详解
📅 发布时间:2026/6/22 0:23:38

MySQL 事务隔离级别详解

关键词:隔离级别、脏读、不可重复读、幻读、MVCC、间隙锁。
重点:搞清楚四个隔离级别分别“允许/禁止”哪些现象,以及 InnoDB 实际是怎么做的。


一、为什么需要事务隔离?

在数据库里,多个事务是并发执行的:

  • 一个事务在读数据;
  • 另一个事务在改数据;
  • 还有一个事务在插入/删除数据。

如果完全不隔离:

  • 你可能读到别人还没提交的修改(脏读);
  • 同一个事务里两次读同一行,结果却不同(不可重复读);
  • 同一个事务里两次按条件查询,前后出现的行数不一样(幻读)。

事务隔离级别就是在:

“读到最新数据” 和 “读到稳定一致的数据” 以及 “系统性能” 之间做平衡。

SQL 标准定义了 4 个隔离级别,对应不同的安全性和性能取舍。


二、三种典型并发现象

先搞清楚几个常见“坏现象”是什么。

2.1 脏读(Dirty Read)

  • 事务 A 读取到了事务 B尚未提交的修改;
  • 如果 B 后面回滚了,A 读到的就是“根本没生效过的假数据”。

示意:

T1: 事务 B:UPDATE account SET balance = balance - 100 WHERE id = 1; T2: 事务 A:SELECT balance FROM account WHERE id = 1; -- 读到了减少 100 后的值 T3: 事务 B:ROLLBACK;

此时事务 A 读到的就是“脏数据”。

2.2 不可重复读(Non-Repeatable Read)

  • 同一个事务中,两次读取同一行数据,结果不一样;
  • 原因是:两次读取之间,别的事务提交了对该行的修改。

示意:

T1: 事务 A:SELECT balance FROM account WHERE id = 1; -- 读到 1000 T2: 事务 B:UPDATE account SET balance = 800 WHERE id = 1; COMMIT; T3: 事务 A:再次 SELECT balance FROM account WHERE id = 1; -- 读到 800

对于一部分业务来说,“同一个事务里两次查应该一致”是刚性需求。

2.3 幻读(Phantom Read)

  • 同一个事务中,两次按某个条件查询,结果的行数不一样;
  • 原因是:两次查询之间,有别的事务插入/删除了满足条件的行。

示意:

T1: 事务 A:SELECT * FROM order WHERE amount > 100; -- 结果 5 行 T2: 事务 B:INSERT INTO order(id, amount) VALUES(100, 200); COMMIT; T3: 事务 A:再次 SELECT * FROM order WHERE amount > 100; -- 结果 6 行

对于“统计 + 校验”等场景,这种“幻影数据”可能会搞乱逻辑。


三、四种事务隔离级别(SQL 标准)

SQL 标准定义了 4 个隔离级别:

  1. READ UNCOMMITTED(读未提交)
  2. READ COMMITTED(读已提交)
  3. REPEATABLE READ(可重复读)
  4. SERIALIZABLE(可串行化)

它们从“弱到强”的对应关系是:

READ UNCOMMITTED < READ COMMITTED < REPEATABLE READ < SERIALIZABLE

隔离越强:

  • 读到的数据越“稳定一致”;
  • 并发性能通常越差。

3.1 READ UNCOMMITTED(读未提交)

特点:

  • 可以读到别的事务尚未提交的修改;
  • 性能最高,但数据安全性最差。

存在问题:

  • ✅ 脏读:可能;
  • ✅ 不可重复读:可能;
  • ✅ 幻读:可能。

这个隔离级别一般不会在生产中使用。


3.2 READ COMMITTED(读已提交)

特点:

  • 每一次查询都只能看到已经提交的最新数据;
  • 每次 SELECT 都会生成一个新的“视图”。

效果:

  • ❌ 脏读:被禁止;
  • ✅ 不可重复读:依然可能;
  • ✅ 幻读:依然可能。

示意:

事务 A: SELECT balance FROM account WHERE id = 1; -- 第一次读 事务 B: UPDATE account SET balance = 800 WHERE id = 1; COMMIT; 事务 A: SELECT balance FROM account WHERE id = 1; -- 第二次读,看到 800

两次读到的结果可能不同,因此称为“读已提交”,而不是“可重复读”。

在很多商业数据库(如 Oracle)中,默认隔离级别就是 READ COMMITTED。


3.3 REPEATABLE READ(可重复读)

特点:

  • 一个事务从开始到结束,看到的数据是一致的“快照”;
  • 同一事务中多次读同一行,结果保持一致;
  • MySQL InnoDB 的默认隔离级别。

效果:

  • ❌ 脏读:禁止;
  • ❌ 不可重复读:禁止(对同一行);
  • ✅ 幻读:按照 SQL 标准定义,理论上仍可能。

但是:

InnoDB 在 REPEATABLE READ 下,配合MVCC + 间隙锁/Next-Key Lock,在大多数场景下也能避免幻读;
只是在严格定义上,仍认为“幻读可能存在某些边界情况”。

示意:

事务 A(RR): 第一次 SELECT * FROM t WHERE id = 1; -- 读到旧版本 事务 B: UPDATE t SET ... WHERE id = 1; COMMIT; -- 提交新值 事务 A: 第二次 SELECT * FROM t WHERE id = 1; -- 仍然读到第一次看到的版本

因为 A 的“视图”是在事务开始时创建的,后续读都以这个视图为准。


3.4 SERIALIZABLE(可串行化)

特点:

  • 最高隔离级别;
  • 强制所有事务看起来像是顺序执行的;
  • 通常通过对读也加锁(类似范围锁/表锁)来实现。

效果:

  • ❌ 脏读:禁止;
  • ❌ 不可重复读:禁止;
  • ❌ 幻读:禁止。

代价是:

  • 并发能力大幅下降;
  • 在高并发场景下一般不建议使用。

四、MySQL InnoDB 中的实际实现细节

4.1 全局 / 会话隔离级别

查看当前隔离级别(MySQL 8.0):

SELECT@@transaction_isolation;-- 或SELECT@@global.transaction_isolation;

设置隔离级别:

-- 设置全局隔离级别SETGLOBALtransaction_isolation='REPEATABLE-READ';-- 设置当前会话隔离级别SETSESSIONtransaction_isolation='READ-COMMITTED';

MySQL 5.x 常用写法(已逐渐被替换):

SELECT@@tx_isolation;SETSESSIONtx_isolation='READ-COMMITTED';

InnoDB 默认隔离级别:REPEATABLE READ。


4.2 READ COMMITTED vs REPEATABLE READ:差别在哪?

核心差别在于一致性视图(Read View)创建时机:

  • READ COMMITTED:

    • 每次 SELECT 都会生成一个新的 Read View;
    • 因此每次查询都能看到当前已经提交的最新版本;
    • 故容易出现“不可重复读”。
  • REPEATABLE READ:

    • 在事务第一次读取数据时创建 Read View;
    • 整个事务期间都复用同一个 Read View;
    • 后续再读同一行,看到的仍然是第一次看到的版本;
    • 避免了不可重复读。

这就是 InnoDB 利用MVCC(多版本并发控制)做出不同隔离语义的核心。


4.3 幻读与间隙锁 / Next-Key Lock

为了控制“幻读”,InnoDB 在可重复读级别下:

  • 对范围查询 + 锁定读(SELECT ... FOR UPDATE / FOR SHARE)会加:
    • 间隙锁(Gap Lock):锁定某个区间,禁止在区间内插入新行;
    • Next-Key Lock:记录锁 + 间隙锁的组合,锁[前一个值, 当前值]区间。

这样:

  • 一个事务在某个范围上进行锁定读或修改;
  • 另一个事务就没法往这个范围内插入新记录;
  • 从而在多数情况下避免了“我查询某条件范围,后面新插入的记录突然冒出来”的幻读问题。

不过:

  • 对纯查询(普通 SELECT 不加锁)来说,避免幻读主要是通过 MVCC 来实现“读到一个旧快照”;
  • 对加锁读来说,则通过 Next-Key Lock + Gap Lock 尽量避免幻读。

五、各隔离级别与并发现象对照表

用一个表总览一下:

隔离级别脏读(Dirty Read)不可重复读(Non-Repeatable)幻读(Phantom)
READ UNCOMMITTED✅ 可能✅ 可能✅ 可能
READ COMMITTED❌ 禁止✅ 可能✅ 可能
REPEATABLE READ*❌ 禁止❌ 禁止✅ 理论上可能*
SERIALIZABLE❌ 禁止❌ 禁止❌ 禁止

说明:

  • 标准语义下,REPEATABLE READ 仍可能有幻读。
  • InnoDB 在 REPEATABLE READ + 间隙锁/Next-Key Lock 下,大部分实际场景中也能避免幻读。

六、怎么选隔离级别?(实践建议)

  1. 绝大多数业务:用默认的 REPEATABLE READ 就够了

    • InnoDB 默认是 REPEATABLE READ;
    • 配合 MVCC 和 Next-Key Lock,能很好平衡一致性和性能。
  2. 如果有强烈的“读最新”需求,可以考虑 READ COMMITTED

    例如:

    • 某些业务要求:一旦事务 B 提交,我的后续读立刻能看到它;
    • 不介意“同一事务内两次读同一行不一样”。
  3. SERIALIZABLE 一般只在一致性要求极端高且并发不大的系统里使用

    • 比如一些对账、结算、强一致金融场景;
    • 否则容易把并发性能打爆。
  4. READ UNCOMMITTED 几乎没有场景需要,基本不要用


七、面试/复习高频问答小抄

Q1:MySQL 默认的事务隔离级别是什么?

  • InnoDB 默认是REPEATABLE READ(可重复读)。

Q2:四个隔离级别分别解决/遗留了哪些问题?

  • READ UNCOMMITTED:什么问题都不解决,允许脏读;
  • READ COMMITTED:解决脏读;不可重复读、幻读仍存在;
  • REPEATABLE READ:解决脏读 + 不可重复读;幻读理论上仍可能;
  • SERIALIZABLE:理论上解决所有问题,但性能最差。

Q3:READ COMMITTED 和 REPEATABLE READ 的实现差别?

  • READ COMMITTED:每次 SELECT 都新建一个 Read View;
  • REPEATABLE READ:事务第一次 SELECT 时创建 Read View,后续复用;
  • 都依赖 MVCC(多版本并发控制)。

Q4:InnoDB 如何处理幻读?

  • 利用MVCC提供一致性视图,使得查询看到的是历史快照;
  • 配合间隙锁(Gap Lock)、Next-Key Lock,在加锁读和更新场景中尽量避免其他事务在范围内插入新行。

Q5:如何查看和设置当前隔离级别?

-- 查看SELECT@@transaction_isolation;-- 设置当前会话SETSESSIONtransaction_isolation='READ-COMMITTED';

八、小结

  1. 事务隔离级别是用来控制并发读写时“看见什么”的规则集合;
  2. MySQL/InnoDB 提供四个级别:读未提交、读已提交、可重复读、可串行化;
  3. 实现手段主要有:
    • MVCC(多版本并发控制):解决大部分读写并发问题;
    • 行锁 + 间隙锁 + Next-Key Lock:控制并发写和“范围插入”;
  4. 日常绝大部分情况:
    • 用 InnoDB 默认的 REPEATABLE READ 就足够;
    • 极端需要读最新且能接受不可重复读时,用 READ COMMITTED。

理解了“隔离级别 = 看见哪些版本的数据 + 加哪些锁”,你基本就把 MySQL 事务隔离级别的本质吃透了。

相关新闻

  • 微信小程序表情包交互:3步打造终极体验指南
  • YOLOv7工业质检实战:AI技术如何将轴承缺陷检测精度提升至99.2%
  • 2025年薪资将超传统行业3倍,未来十年最火的黄金赛道!人才缺口高达327万

最新新闻

  • 扩散语言模型并行解码:DMax架构突破性能瓶颈
  • ATROPOS:基于图神经网络与早期终止的LLM智能体成本优化方案
  • Debian 10 日志集中化:用 systemd-journal-remote 构建结构化日志链
  • 大语言模型空间推理能力研究:基于TEXT2SPACE与ASCII增强
  • Ghost CMS生产环境接管指南:从DigitalOcean一键部署到稳定运维
  • Debian 8 安装 Java 的三大可行方案:apt/离线/二进制免装

日新闻

  • 2026速览惠州叛逆青少年学校前十大排名名单出炉 - 武汉中职最新信息发布
  • 2026上饶白蚁消杀哪家好?15年本土2大权威白蚁防治公司推荐(金盾虫控/青蚁卫士) - 我叫一
  • 天龙八部单机版终极数据管理工具:5个技巧快速掌握游戏数据编辑

周新闻

  • Visual C++运行库修复终极指南:5分钟快速解决Windows软件启动错误
  • 手把手教你构建统计局地区经济数据爬虫:从环境搭建到数据持久化全指南
  • 2026多Agent深度解析:用AI团队替代单一模型,四种架构实战落地

月新闻

  • 【总结】入门篇:50句话让你记住架构核心概念
  • WeChatMsg技术方案解析:实现Mac微信数据自主管理的完整解决方案
  • WeChatMsg:革新性微信数据备份方案,打造你的专属数字记忆库

关于尧图

  • 公司简介
  • 团队介绍
  • 企业文化
  • 荣誉资质

服务项目

  • 定制开发
  • 电商建站
  • UI 设计
  • 运维服务

快速链接

  • 案例展示
  • 建站流程
  • 常见问题
  • 资讯中心

联系方式

  • 📍北京市朝阳区互联网产业园 A 座 10 层
  • 📞400-888-8888
  • ✉️contact@rkmt.cn
  • 🕐周一至周日 9:00-21:00

© 2024 北京尧图网络科技有限公司 版权所有 | 京 ICP 备 XXXXXXXX 号