简短回答:不完全靠隔离级别(隔离性)来避免幻读,但隔离性(特别是“可串行化”隔离级别)是最主要、最标准的避免手段;在某些数据库里,也可以通过锁或 MVCC 机制在较低隔离级别下缓解,但严格意义上的“避免幻读”通常依赖隔离级别。
下面展开说清楚。
幻读(Phantom Read):
在同一个事务中,两次执行相同的范围查询,第二次查询看到了第一次查询时不存在的行(通常是其他事务新插入/删除并提交的数据)。
例子:
-- 事务 A
SELECT * FROM orders WHERE amount > 100;
-- 事务 B 插入一条 amount=200 的订单并提交
-- 事务 A 再次执行
SELECT * FROM orders WHERE amount > 100;
A 看到了“多出来”的行 → 幻读。
注意:
- 脏读:读未提交
- 不可重复读:同一条记录值变了
- 幻读:结果集行数/内容变了(新行出现)
以 SQL 标准隔离级别为例:
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 | ❌ | ❌ | ❌ |
| 读已提交 | ✅ | ❌ | ❌ |
| 可重复读 | ✅ | ✅ | ❌* |
| 可串行化 | ✅ | ✅ | ✅ |
*MySQL InnoDB 的「可重复读」通过 MVCC + 间隙锁,很大程度上避免了幻读,但这不是 SQL 标准定义,而是实现层面的增强。
可以,但是“手动”:
SELECT * FROM orders WHERE amount > 100 FOR UPDATE;
幻读主要靠“隔离性”来避免,尤其是:
如果你愿意,我可以:
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。