在数据库事务管理中,脏读(Dirty Read)、不可重复读(Non-repeatable Read)、幻读(Phantom Read) 是三种常见的读一致性问题,它们与事务的隔离级别密切相关。
一、三种读问题的定义
1. 脏读(Dirty Read)
- 定义:事务 A 读取到了事务 B未提交的数据变更。
- 例如:事务 B 修改了某条记录但未提交,此时事务 A 读取该记录,若事务 B 随后回滚,事务 A 读取到的就是无效的 “脏数据”。
- 后果:导致数据不一致,破坏事务的隔离性。
2. 不可重复读(Non-repeatable Read)
- 定义:事务 A 在同一事务中两次读取同一数据时,得到不同结果(因其他事务在期间提交了对该数据的修改)。
- 例如:事务 A 先读取记录的年龄为 20,事务 B 修改该记录年龄为 22 并提交,事务 A 再次读取时年龄变为 22,两次结果不一致。
- 关注点:针对单行数据的修改,强调数据内容的变化。
3. 幻读(Phantom Read)
- 定义:事务 A 在同一事务中两次执行相同查询时,结果集的行数发生变化(因其他事务在期间插入或删除了符合条件的记录)。
- 例如:事务 A 查询年龄 > 20 的用户有 3 条记录,事务 B 插入一条年龄 25 的记录并提交,事务 A 再次查询时结果变为 4 条,仿佛 “幻觉” 出现新数据。
- 关注点:针对数据行的插入 / 删除,强调结果集的行数变化。
二、数据库隔离级别(SQL 标准)
为解决上述问题,SQL 标准定义了四种隔离级别,从低到高依次为:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 性能 |
|---|---|---|---|---|
| 读未提交(Read Uncommitted) | 允许 | 允许 | 允许 | 最高 |
| 读已提交(Read Committed) | 禁止 | 允许 | 允许 | 较高 |
| 可重复读(Repeatable Read) | 禁止 | 禁止 | 部分禁止 | 中等 |
| 可串行化(Serializable) | 禁止 | 禁止 | 禁止 | 最低 |
1. 读未提交(Read Uncommitted)
- 特性:最低隔离级别,事务可读取其他事务未提交的数据。
- 问题:会出现脏读、不可重复读、幻读。
- 适用场景:对一致性要求极低,追求高并发性能(如日志统计)。
2. 读已提交(Read Committed)
- 特性:事务只能读取其他事务已提交的数据。
- 解决问题:避免脏读,但仍存在不可重复读和幻读。
- 数据库实现:
- 大多数数据库(如 Oracle、SQL Server)的默认隔离级别。
- MySQL 的 InnoDB 引擎通过 **MVCC(多版本并发控制)** 实现此级别,查询时读最新提交的版本。
3. 可重复读(Repeatable Read)
- 特性:保证同一事务内多次读取相同数据时结果一致(其他事务提交的修改在本事务中不可见)。
- 解决问题:避免脏读和不可重复读,但幻读问题未完全解决(不同数据库实现有差异)。
- MySQL 的 InnoDB:通过MVCC和 ** 间隙锁(Gap Lock)** 机制,在 RR 级别下可禁止幻读(默认配置)。
- Oracle/SQL Server:RR 级别仍可能存在幻读,需手动加锁处理。
- 适用场景:多数业务场景(如金融交易、库存管理),兼顾一致性和性能。
4. 可串行化(Serializable)
- 特性:最高隔离级别,通过强制事务串行执行(类似单线程)避免所有并发问题。
- 解决问题:完全避免脏读、不可重复读、幻读。
- 缺点:性能开销极大,并发能力极低。
- 适用场景:对一致性要求极高且并发量低的场景(如银行转账核心系统)。
三、总结对比
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | 实现方式 | 典型场景 |
|---|---|---|---|---|---|
| 读未提交 | 允许 | 允许 | 允许 | 无锁,直接读取未提交数据 | 日志分析、非关键统计 |
| 读已提交 | 禁止 | 允许 | 允许 | 锁或 MVCC(读已提交版本) | 普通业务查询(如电商) |
| 可重复读 | 禁止 | 禁止 | 部分禁止 | MVCC + 行锁 / 间隙锁(如 InnoDB) | 金融交易、库存管理 |
| 可串行化 | 禁止 | 禁止 | 禁止 | 全表锁或强制串行执行 | 高一致性、低并发场景 |
四、数据库实现差异
- MySQL InnoDB:默认隔离级别为可重复读(RR),通过 MVCC 和间隙锁解决幻读。
- Oracle:默认隔离级别为读已提交(RC),不支持可重复读下的幻读防护。
- SQL Server:默认隔离级别为读已提交(RC),可通过配置开启快照隔离(Snapshot Isolation)优化。
实际开发中需根据业务一致性需求和性能要求选择合适的隔离级别,避免过度设计或一致性不足的问题。



2935

被折叠的 条评论
为什么被折叠?



