贝利信息

SQL数据库幻读形成条件_范围查询分析

日期:2026-01-08 00:00 / 作者:冷炫風刃
幻读指事务中范围查询返回不一致行数,因其他事务插入新行被后续查询感知;需满足RR或更低隔离级、范围查询、并发插入三条件;MVCC快照读不覆盖新插入行,故仍发生幻读。

幻读发生在事务中执行相同范围查询时,返回了前后不一致的行数,尤其是出现了“新插入的、本不该看到的记录”。它不是脏读或不可重复读,核心在于其他事务在当前事务的查询范围内插入了新行,并且这些插入被当前事务后续查询“感知”到了。

幻读形成的三个必要条件

只有同时满足以下三点,幻读才可能发生:

为什么 MVCC 在 RR 级别下仍可能发生幻读

MySQL 的 RR 级别基于 MVCC 实现快照读(普通 SELECT),它能看到事务启动时已提交的数据版本,但不保证未来不会出现新版本的行。MVCC 解决了不可重复读(同一行值变化),但对“新插入的行”,快照里本来就没有,所以第二次查询会自然读到新提交的行——这就是幻读的本质:读到了快照之外“新生”的记录。

注意:MySQL InnoDB 对当前读(如 SELECT ... FOR UPDATE、UPDATE、DELETE)会加临键锁(Next-Key Lock),即记录锁 + 间隙锁,能阻塞范围内的插入,从而避免当前读下的幻读;但快照读不受此保护。

典型场景还原:订单状态范围查询

假设业务需统计“待处理订单(status = 0)的数量”,并在统计后批量更新:

这个过程体现了幻读带来的逻辑错位:统计与操作作用于不同数据集。

如何真正避免幻读

不能只依赖隔离级别,需结合具体读写类型选择策略: