贝利信息

SQL 幻读真的存在吗?

日期:2026-01-20 00:00 / 作者:舞夢輝影
幻读确实存在,指同一事务两次范围查询间因

其他事务插入并提交新行而导致结果集新增满足条件的记录;它发生在可重复读级别,尤其在当前读场景下暴露,可通过间隙锁、唯一约束或串行化避免。

幻读确实存在,而且是数据库事务隔离级别中一个真实、可复现的现象,不是理论假设或误读。

什么是幻读

幻读指:在一个事务内,**两次执行相同的范围查询(如 SELECT ... WHERE age > 25)**,第二次查询结果中出现了第一次没有的“新行”,这些行是其他事务在此期间插入并提交的。它和不可重复读不同——不可重复读是同一行数据被修改,而幻读是“凭空多出”了满足条件的新记录。

注意:幻读关注的是 行数变化新符合查询条件的记录出现,不是简单地看到别人插入的任意数据。

幻读在哪些隔离级别下会发生

幻读主要出现在 可重复读(Repeatable Read) 隔离级别下(尤其在 MySQL InnoDB 中需结合具体语句理解)。很多人误以为 RR 能完全避免幻读,其实不然:

怎么验证幻读(以 MySQL 为例)

你可以用两个会话手动复现:

这个过程清晰展示了幻读的发生机制:不是 MVCC 失效,而是当前读绕过了快照,直接访问最新状态,同时原事务未锁定插入间隙。

如何避免幻读

真正解决幻读,不能只靠隔离级别升级(因为最高级别串行化性能代价大),而要结合机制和设计: