幻读指同一事务两次查询相同条件时行数不一致,因其他事务插入/删除导致结果集变化;MySQL在RR级别下通过MVCC避免快照读幻读,用next-key lock防止当前读幻读,但混合读取仍可能引发逻辑问题。
幻读是 MySQL 事务中一种典型的并发一致性问题,指同一个事务在相同查询条件下,两次读取返回的**行数不一致**——第二次读到了第一次没有的“新行”,就像看到了幻影一样。
它和脏读、不
可重复读有本质区别:
典型场景:事务 A 查询 SELECT * FROM orders WHERE status = 'pending' 得到 5 条;事务 B 插入一条新 pending 订单并提交;事务 A 再次执行相同语句,得到 6 条——这多出的 1 条就是“幻行”。
答案是:部分解决,但不彻底。InnoDB 在可重复读(Repeatable Read)下通过两种机制协同应对:
但注意:如果一个事务先做快照读,之后又做当前读,且中间有其他事务插入并提交,就可能出现“快照读看不到、当前读却看到”的现象。严格来说,这不算标准幻读(因读类型不同),但业务上仍可能造成逻辑混乱。
只有提升隔离级别或主动加锁:
SELECT ... FOR UPDATE 锁定范围,确保后续操作基于一致的快照+锁定区间;因为多数简单查询是快照读,MVCC 已屏蔽大部分幻读风险;但一旦涉及“先查后更”“范围统计+写入”等复合操作,幻读就容易暴露。比如库存扣减前查余量、生成报表后再导出明细、分页查询时总条数与实际页数据不匹配等场景,都需特别警惕。