数据库系统工程师 · 事务隔离 · 并发控制

脏读、不可重复读和幻读怎么区分?

事务隔离题最容易错在“都像是读到了不该读的数据”。其实脏读、不可重复读和幻读问的不是同一个层面的事。老师讲这类题时,通常会先把它们拆成三句话:脏读看未提交,不可重复读看同一行,幻读看一批行。

数据库系统工程师专题 软考题库编辑部 持续更新

先问:读到的数据提交了吗?

脏读的核心是读到了另一个事务尚未提交的数据。注意“未提交”三个字,这是脏读和另外两个概念最直接的分界线。比如事务 A 修改了账户余额但还没提交,事务 B 已经读到了这个新余额;后来事务 A 回滚,事务 B 之前读到的就是不可靠的数据。

考试题干如果反复强调“另一个事务尚未提交”“随后回滚”“读到了临时数据”,优先想到脏读。不要一看到两次读取结果不同就马上选不可重复读,先看第一次读到的值是不是来自未提交事务。

并发异常核心判断老师提醒
脏读读到未提交数据关键词是未提交、回滚、临时结果
不可重复读同一行数据前后读取结果不同关键词是同一条记录被修改或删除
幻读同一范围内记录数量变化关键词是一批记录、多出或少了行
丢失更新两个事务更新互相覆盖关键词是后写覆盖前写

不可重复读盯的是“同一行”

不可重复读通常发生在一个事务内,两次读取同一条记录,结果不一样。原因可能是另一个事务在中间修改并提交了这条记录。它关注的是一条已经存在的记录值发生变化,或者这条记录被删除。

例如事务 A 第一次查询订单 1001 的状态是“待支付”,事务 B 把它改成“已支付”并提交,事务 A 第二次再查订单 1001,状态变了。这个例子里,不是多了一批新订单,而是同一条订单前后不一致。

考场小口诀

脏读:读到了别人还没确认的草稿。

不可重复读:同一条记录,前后读出来不一样。

幻读:同一个查询范围,第二次像多了或少了几条记录。

幻读盯的是“范围里的记录数”

幻读看起来也像前后查询不一致,但它通常不是同一行的字段值变了,而是某个范围查询的结果集变了。比如事务 A 查询“金额大于 1000 的订单”得到 5 条记录;事务 B 插入一条金额 2000 的订单并提交;事务 A 再查同样条件,变成 6 条。

这就是为什么很多老师会说:不可重复读看一行,幻读看一批。只要题干出现范围查询、满足条件的记录数量、插入新记录这类描述,就要警惕幻读,而不是只按“第二次结果不同”去判断。

题干描述更可能是不要误判为
读到了未提交后又回滚的数据脏读不可重复读
同一订单状态前后不同不可重复读幻读
同一条件查询多出几条记录幻读不可重复读
两个事务同时改库存,后提交覆盖前提交丢失更新脏读

隔离级别不是越高越随便选

事务隔离级别越高,通常能减少更多并发异常,但并发性能也可能下降。考试不会只让你喊“串行化最安全”,更常见的是让你理解不同隔离级别为什么存在:系统需要在正确性和并发性能之间做取舍。

复习时可以把这类题放在 ACID 的 Isolation 下面理解。隔离性不是一句“互不影响”就结束了,它具体会落到脏读、不可重复读、幻读这些可观察的问题上。题干一旦出现这几个词,先别想索引、备份和视图,先回到事务隔离。

相关题目解析

下面这些题目和本专题的判断方法关联较强,适合读完概念后回到具体题干里校验理解。