简短结论:在 MySQL InnoDB 的“可重复读(REPEATABLE READ)”隔离级别下,MVCC 能很大程度上避免“快照读”的幻读,但不能完全避免“当前读”的幻读;在标准 SQL 语义和某些场景下,MVCC 本身并不能完全避免幻读。
下面分层说明。
幻读(Phantom Read)指:
注意:幻读强调的是insert 导致的新行,不是 update 导致的数值变化。
MVCC(多版本并发控制)核心思想:
在 REPEATABLE READ 下:
✅ 所以:
普通 SELECT(快照读)不会看到幻行
示例(MySQL InnoDB,RR 级别):
-- 事务A
START TRANSACTION;
SELECT * FROM user WHERE age > 20; -- 看到 2 条
-- 事务B
INSERT INTO user(age) VALUES (25);
COMMIT;
-- 事务A
SELECT * FROM user WHERE age > 20; -- 仍然看到 2 条(MVCC 生效)
✅ 这里 MVCC 避免了幻读
以下语句不是快照读,而是当前读:
SELECT ... FOR UPDATESELECT ... LOCK IN SHARE MODEUPDATE / DELETE示例:
-- 事务A
START TRANSACTION;
SELECT * FROM user WHERE age > 20 FOR UPDATE;
-- 事务B
INSERT INTO user(age) VALUES (25);
COMMIT;
-- 事务A
SELECT * FROM user WHERE age > 20 FOR UPDATE;
-- 看到了新插入的行 → 幻读
❌ MVCC alone 不够
✅ 解决方式:Next-Key Lock(间隙锁 + 记录锁)
InnoDB 在 REPEATABLE READ 下:
两者结合,使得 MySQL 的 RR 级别在工程中几乎避免了幻读
但这是:
MVCC + 锁机制 共同的结果
不是 MVCC 单独完成的
MVCC 能避免快照读下的幻读,但不能避免当前读下的幻读;MySQL 通过 MVCC + Next-Key Lock 在 RR 级别几乎完全避免幻读。
如果你愿意,我也可以用图解版本链 / 快照生成时机 / 锁范围示例来进一步说明。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。