当前位置: 首页 > news >正文

深入 ACID 与事务隔离级别

在第二阶段的事务入门篇中,我们认识了事务的基本概念,学习了COMMITROLLBACK,并初步体验了脏读现象。那时我们留下了一个伏笔:ACID 到底是如何实现的?四种隔离级别背后发生了什么?

从本篇开始,我们将进入 MySQL 最精彩的部分之一——事务进阶、锁机制与并发控制。本文作为第五阶段的开篇,将系统性地回答:

  • ACID 四个特性在 InnoDB 中分别由哪些技术实现
  • 四种隔离级别的严格定义与区别
  • 脏读、不可重复读、幻读的本质与重现
  • 隔离级别的设置与选择
  • 实战:亲手验证READ UNCOMMITTED下的脏读

读完本文,你将能够自信地解释“为什么 MySQL 能保证事务一致性”,并根据业务需求灵活选择隔离级别。


1. ACID 的实现原理:谁在背后干活?

ACID 是事务正确性的四个基石,但它们并非“天生就有”,而是由 InnoDB 的多个组件协同实现的。

1.1 原子性(Atomicity)—— Undo Log 负责

原子性要求一个事务中的所有操作要么全部成功,要么全部失败。已经执行了一半的操作必须能被撤销。

InnoDB 通过Undo Log实现原子性:

  • 在修改任何行之前,先将旧值记录到 Undo Log 中。
  • 如果事务执行ROLLBACK,就沿着 Undo Log 将数据恢复成旧版本。
  • Undo Log 记录的是逻辑变化(如“这行之前的值是 X”),而不是物理页的字节翻转。

1.2 持久性(Durability)—— Redo Log 负责

持久性要求一旦事务提交,其修改就永久保存,哪怕系统崩溃。

InnoDB 通过Redo Log + WAL(Write-Ahead Logging)实现持久性:

  • 修改数据页之前,先把“做了什么修改”记录到 Redo Log,并确保 Redo Log 落盘。
  • 事务提交时,Redo Log 必须已经写入磁盘(由innodb_flush_log_at_trx_commit控制)。
  • 崩溃恢复时,从最后一次 Checkpoint 开始重做 Redo Log,恢复所有已提交的修改。

1.3 隔离性(Isolation)—— 锁 + MVCC 负责

隔离性要求并发事务之间互不干扰。一个事务执行过程中,不应该看到其他事务未提交的修改。

InnoDB 通过锁机制(Lock)多版本并发控制(MVCC)共同实现隔离性:

  • 行锁:写操作会对行加排他锁,防止其他写操作同时修改同一行。
  • MVCC:读操作不加锁,通过 Undo Log 构建的版本链和 ReadView 实现“无锁读”,读到的是该事务应该看到的版本。
  • 不同隔离级别决定了 ReadView 的生成时机以及锁的粒度,从而在并发性和一致性之间做出权衡。

1.4 一致性(Consistency)—— 由其他三者 + 应用层保证

一致性要求事务执行前后,数据库必须处于一致状态(所有约束都满足,业务规则不被打破)。

一致性是 ACID 的最高层目标,由原子性、隔离性、持久性以及数据库的约束(主键、外键、CHECK 等)和应用程序的业务逻辑共同实现。如果应用层写入的逻辑本身不正确(比如转账时只扣钱不加钱),数据库无法自动阻止,因此一致性也依赖于应用开发者的正确实现。


2. 四种事务隔离级别:严格定义与区别

SQL 标准定义了四种隔离级别,依次更严格地解决三类并发问题。

2.1 三类并发问题回顾

在事务入门篇我们介绍过,这里再严格定义一遍:

  • 脏读(Dirty Read):事务 T1 读到了事务 T2未提交的修改数据。如果 T2 回滚,T1 读到的就是“脏数据”。
  • 不可重复读(Non-Repeatable Read):事务 T1 内两次读取同一行数据,结果不同。因为 T2 在 T1 两次读取之间修改并提交了该行。
  • 幻读(Phantom Read):事务 T1 内两次执行同一范围查询,返回的行数不同。因为 T2 在两次查询之间插入或删除了符合条件的行,并提交了。

不可重复读关注的是行内容的修改,幻读关注的是行数量的变化。

2.2 四种隔离级别对比

隔离级别脏读不可重复读幻读
READ UNCOMMITTED可能可能可能
READ COMMITTED不可能可能可能
REPEATABLE READ不可能不可能可能(InnoDB 通过 Next-Key Lock 防止大部分幻读)
SERIALIZABLE不可能不可能不可能
READ UNCOMMITTED(读未提交)

最宽松的级别。事务可以读到其他事务未提交的数据。几乎没有任何并发控制,一致性极差,极少在生产中使用。

READ COMMITTED(读已提交)

大多数数据库的默认级别(如 Oracle、PostgreSQL)。一个事务只能读到其他事务已提交的修改。解决了脏读,但仍然存在不可重复读和幻读。

InnoDB 在 RC 级别下,每次快照读都会生成新的 ReadView,因此可以在同一事务中看到不同时间的已提交数据。

REPEATABLE READ(可重复读)

MySQL InnoDB 的默认级别。同一个事务内的多次读取结果一致(解决了不可重复读)。对于幻读,InnoDB 通过Next-Key Lock(行锁 + 间隙锁)在很大程度上进行了抑制,但并不是完全不可能。

在 RR 级别,InnoDB 在事务第一次读取时生成一个 ReadView,之后一直沿用这个视图,因此总能看到事务开始时的数据快照。

SERIALIZABLE(可串行化)

最高隔离级别。所有事务串行执行(通过加锁实现),读操作也会加共享锁。完全避免了脏读、不可重复读和幻读,但并发性能极差,几乎不用。

2.3 InnoDB 中 REPEATABLE READ 的“半”幻读

理论上 RR 无法防止幻读,但 InnoDB 通过Next-Key Lock将行锁和间隙锁组合,使得其他事务无法在已查询的范围内插入新行。这阻止了典型的幻读场景(比如SELECT ... FOR UPDATE的范围查询)。

然而,如果先快照读再当前读,或者在同一事务中先快照读、其他事务插入并提交,当前事务再执行UPDATE可能影响原本看不到的行。这种“半幻读”现象偶尔会在特殊逻辑中遇到,后续《幻读与 Next-Key Lock》篇会深入分析。


3. 设置隔离级别

-- 查看当前会话隔离级别SELECT@@transaction_isolation;-- 查看全局隔离级别SELECT@@global.transaction_isolation;-- 设置当前会话的隔离级别SETSESSIONTRANSACTIONISOLATIONLEVELREADUNCOMMITTED;SETSESSIONTRANSACTIONISOLATIONLEVELREADCOMMITTED;SETSESSIONTRANSACTIONISOLATIONLEVELREPEATABLEREAD;SETSESSIONTRANSACTIONISOLATIONLEVELSERIALIZABLE;-- 设置全局(重启后恢复为配置文件中的值)SETGLOBALTRANSACTIONISOLATIONLEVELREADCOMMITTED;

全局设置影响之后新建立的连接,已有连接不受影响。生产环境更改需谨慎,可以通过配置文件transaction-isolation永久设置。


4. 实战:验证 READ UNCOMMITTED 下的脏读

我们来直观地感受一下脏读的危害。需要开启两个会话,按照以下步骤操作。

4.1 准备测试表

CREATEDATABASEIFNOTEXISTSiso_test;USEiso_test;CREATETABLEaccount(idINTPRIMARYKEY,balanceINTNOTNULL)ENGINE=InnoDB;INSERTINTOaccountVALUES(1,1000);

4.2 会话 A(修改但未提交)

SETSESSIONTRANSACTIONISOLATIONLEVELREADUNCOMMITTED;STARTTRANSACTION;UPDATEaccountSETbalance=888WHEREid=1;-- 不提交

4.3 会话 B(脏读)

SETSESSIONTRANSACTIONISOLATIONLEVELREADUNCOMMITTED;SELECT*FROMaccountWHEREid=1;

结果:balance = 888—— 会话 B 读到了会话 A 尚未提交的修改!这就是脏读。

4.4 会话 A 回滚

ROLLBACK;

4.5 会话 B 再次查询

SELECT*FROMaccountWHEREid=1;

结果:balance = 1000—— 会话 B 之前读到的 888 变成“假数据”,基于它的业务决策(如扣款)将导致严重错误。

4.6 切换到 READ COMMITTED 避免脏读

会话 B 将隔离级别改为READ COMMITTED

SETSESSIONTRANSACTIONISOLATIONLEVELREADCOMMITTED;

重新执行上述步骤,会话 B 在会话 A 未提交时读到的仍然是1000,脏读消失。

4.7 清理

DROPDATABASEiso_test;

5. 隔离级别选择指南

在实际项目中,隔离级别并非越高越好,需要权衡一致性和并发性能:

  • REPEATABLE READ(InnoDB 默认):兼顾数据一致性和并发性能,适合大多数业务场景。不用担心不可重复读,Next-Key Lock 也能防止大多数幻读。
  • READ COMMITTED:适合对一致性要求稍低、但需要更高并发的场景(如互联网高并发写入)。缺点是同一事务内两次读可能不同,并且无法完全防止幻读。在基于语句的复制(SBR)中,RC 可能导致主从数据不一致,需要切换为基于行的复制(RBR)。
  • READ UNCOMMITTED:几乎不用。除非是纯只读且允许脏数据的场景(极少)。
  • SERIALIZABLE:极少使用,仅在对数据一致性要求绝对严格且并发量极低的场景下考虑。

6. 小结

本文我们从实现原理和并发问题两个维度,彻底吃透了 ACID 和隔离级别:

  • ACID 的实现:Undo Log 保障原子性,Redo Log + WAL 保障持久性,锁 + MVCC 保障隔离性,三者加上约束与业务逻辑共同实现一致性。
  • 三种并发问题:脏读(读未提交)、不可重复读(同一行被修改提交)、幻读(范围查询行数变化)。
  • 四种隔离级别:READ UNCOMMITTED(问题全开放)→ READ COMMITTED(防脏读)→ REPEATABLE READ(防脏读和不可重复读)→ SERIALIZABLE(全防)。
  • InnoDB 的默认 RR通过 Next-Key Lock 在很大程度上抑制了幻读。
  • 通过实战亲手验证了READ UNCOMMITTED下的脏读现象,并对比了READ COMMITTED的正确行为。

事务的隔离性离不开锁。下一篇,我们将深入到锁的分类:表锁、行锁、页锁、意向锁,以及共享锁与独占锁的区别,为后续理解 Next-Key Lock 和 MVCC 打下基础。

思考题

  1. 如果在REPEATABLE READ隔离级别下,事务 A 先读取了一条数据,然后事务 B 修改并提交,事务 A 再次读取该数据,读到的是什么值?为什么?
  2. 为什么SERIALIZABLE级别并发性能差?它使用了什么机制?
  3. 尝试将你的测试环境隔离级别设为READ COMMITTED,模拟一下不可重复读的场景(两个会话交替读写)。

参考资料

  • MySQL 8.0 Reference Manual - Transaction Isolation Levels
  • MySQL 8.0 Reference Manual - InnoDB Multi-Versioning
  • MySQL 8.0 Reference Manual - ACID Model

http://www.jsqmd.com/news/977042/

相关文章:

  • 从原理看 Arthas 为何比 IDEA Profiler 更“懂”你的代码
  • 2026年苏州公司注册代办/代理记账/工商变更/高新认定十大服务商榜单:专业资质与创业扶持全解析 - 品牌发掘
  • 3步打造完美黑苹果:OpCore-Simplify智能EFI生成工具实战指南
  • 3步解锁AMD Ryzen处理器隐藏性能:SMU Debug Tool新手完全指南
  • 2026小程序开发公司哪家好?推荐10家实力型小程序制作公司
  • 免费视频翻译神器:pyVideoTrans让你3步搞定多语言视频制作
  • Vue i18n动态加载进阶:结合Pinia/Vuex管理多语言状态与接口缓存策略
  • LSTM 文本情感分析:从词嵌入到分类实战
  • 拆解 SSE 流式统一封装:解决各大模型流式格式不统一难题
  • 哔咔漫画下载器终极指南:快速搭建个人离线漫画库的完整方案
  • LangGraph+ElevenLabs构建可控AI播客生产流水线
  • ESM 与 ESMFold:当蛋白质序列成为生命语言
  • Origin 2018论文绘图避坑指南:搞定双Y轴、不均匀柱状图与Word图片尺寸
  • Adobe-GenP:颠覆性破解工具的全新视角,3分钟解锁Adobe全家桶的革命性方案
  • 手把手教你用C语言实现SM4国密算法(仅用stdio.h,附完整可运行代码)
  • 嵌入式安全芯片中间件移植实战:从Linux到RTOS的平台适配指南
  • LLM 结构化输出与 JSON Schema 约束:从 Prompt 到可靠解析的工程实践
  • 商业旅拍后期修图痛点全攻克:像素蛋糕一站式AI精修方案
  • GPT-4 Turbo工程落地指南:上下文、JSON模式与Assistants API避坑实战
  • 3大核心功能+5分钟上手:用OpenDroneMap将无人机照片变身高精度3D地图
  • 手把手教你用C#对接爱发电API:基于Afdian.Sdk的完整开发指南
  • 从MKW36到MKW38:蓝牙LE嵌入式无线MCU平台迁移实战指南
  • 2026年成都托福机构排名实测:成都大学生真实测评,5家主流机构怎么选? - 新闻快传
  • Temu全托陪跑综合评估:专业背景、结果保障、风险控制、口碑数据怎么判断 - 麦克杰
  • Mythos门控发布:AI模型自我校验与可控澄清技术解析
  • 卡梅德生物技术快报|同位素标记制备碳纳米材料及全流程示踪检测方案
  • 行业变局:缝制制造正式进入「计划能力定义企业产能」的竞争下半场
  • 数学建模竞赛论文写作实战:从LaTeX模板到图表美化,让你的论文脱颖而出
  • i.MX 8M Nano到i.MX 93迁移:电源管理架构与DVFS/VFS配置实战解析
  • RAG 向量检索优化:HNSW 索引调参与混合检索策略的工程实践