面包屑图标 当前位置: 首页
AI资讯
热点详情

事务隔离级别选错导致数据被吞 脏读幻读一次讲透

AI热点日报
AI热点日报时间:2026-07-14
热点解读

你在开发过程中,有没有遇到过这样的情况:一个事务里查了两次同样的数据,结果居然不一样;或者查了两次同样的范围条件,结果集凭空多了一行?很多人第一反应是“是不是缓存出问题了”,但其实,更大的概率是事务隔离级别没选对。 事务隔离级别,简单来说就是决定多个事务同时运行时,彼此能看到多少对方的数据。选得太低

你在开发过程中,有没有遇到过这样的情况:一个事务里查了两次同样的数据,结果居然不一样;或者查了两次同样的范围条件,结果集凭空多了一行?很多人第一反应是“是不是缓存出问题了”,但其实,更大的概率是事务隔离级别没选对。

事务隔离级别,简单来说就是决定多个事务同时运行时,彼此能看到多少对方的数据。选得太低,数据可能被“污染”;选得太高,并发性能又会急剧下降。今天这篇文章,我们就从四个隔离级别出发,把脏读、不可重复读、幻读这三个概念,掰开揉碎讲清楚。

先搞懂四个隔离级别

SQL标准定义了四种隔离级别,从低到高依次是:

1. READ UNCOMMITTED(读未提交) ——级别最低。事务可以读取其他事务尚未提交的数据。几乎不提供任何并发控制,实际生产环境中极少见到它的身影。

2. READ COMMITTED(读已提交,简称RC) ——只能读取其他事务已经提交的数据。它成功避免了脏读,但无法避免不可重复读。

3. REPEATABLE READ(可重复读,简称RR) ——保证同一事务内多次读取同一数据,结果完全一致。这也是MySQL InnoDB的默认隔离级别。

4. SERIALIZABLE(可串行化) ——最高级别,事务完全串行执行,从根源上杜绝所有并发问题,但性能开销也是最大的。

不同隔离级别能解决的问题,可以浓缩成下面这张表:

隔离级别 脏读 不可重复读 幻读
READ UNCOMMITTED 可能 可能 可能
READ COMMITTED 避免 可能 可能
REPEATABLE READ 避免 避免 InnoDB基本避免
SERIALIZABLE 避免 避免 避免

三种并发问题,用真实SQL讲清楚

脏读:读到别人“还没想好”的数据

脏读,指的是一个事务读取了另一个事务尚未提交的修改。如果那个事务最终回滚了,你读到的就是“脏数据”——从未真正存在过的数据。

用电商库存场景来理解:事务A开始扣减库存,把商品X的库存从100改为99,但还没提交;此时事务B查询库存,读到了99。如果事务A因支付失败回滚了,库存恢复为100,但事务B已经基于99做了后续操作——超卖了。

-- 事务A(未提交)
START TRANSACTION;
UPDATE products SET stock = stock - 1 WHERE id = 1;  -- stock从100变99
-- 此时事务B读取到stock=99(未提交的数据)
-- 事务A回滚
ROLLBACK;  -- stock恢复为100,但事务B已经用了99的数据


想要解决脏读,至少要把隔离级别设置为READ COMMITTED。

不可重复读:同一事务内,数据“变了”

不可重复读指的是在同一个事务内,多次读取同一数据时结果不一致。它与脏读的关键区别在于:脏读读的是未提交的数据,而不可重复读读的是已提交的数据。

用财务场景来理解:财务人员在事务A中查询员工张三的工资,第一次看到5000元;此时HR在事务B中给张三加薪至6000元并提交;事务A再次查询时,工资变成了6000元。同一个事务里两次查询结果不一样——这就是不可重复读。

-- 事务A(隔离级别READ COMMITTED)
START TRANSACTION;
SELECT salary FROM employees WHERE id = 1;  -- 返回5000

-- 事务B(同时执行)
START TRANSACTION;
UPDATE employees SET salary = 6000 WHERE id = 1;
COMMIT;  -- 提交修改

-- 事务A再次查询
SELECT salary FROM employees WHERE id = 1;  -- 返回6000,和第一次不一样
COMMIT;


READ COMMITTED级别无法避免这个问题。你需要升级到REPEATABLE READ。

幻读:结果集“凭空多了一行”

幻读指的是在同一个事务内,多次查询某个范围的数据时,结果集的数量发生了变化——第一次查有5行,第二次查变成了6行。

打个比方:你在图书馆按分类找书,第一次看到书架上有5本书;等你转了一圈回来再数,变成了6本——多出来那本就是你不在的时候别人放上去的。

-- 事务A(隔离级别REPEATABLE READ)
START TRANSACTION;
SELECT * FROM orders WHERE status = 'pending';  -- 返回5行

-- 事务B(同时执行)
START TRANSACTION;
INSERT INTO orders (id, status) VALUES (100, 'pending');
COMMIT;

-- 事务A再次查询
SELECT * FROM orders WHERE status = 'pending';  -- 返回6行,多了一行!
COMMIT;


MySQL的RR为什么能“基本避免”幻读?

按照SQL标准,REPEATABLE READ级别实际上是允许幻读的。但MySQL InnoDB通过MVCC(多版本并发控制)+ Gap Lock(间隙锁) 的组合拳,在绝大多数场景下实实在在地避免了幻读的发生。

  • MVCC​:事务开始时拍一次快照,后续的普通SELECT都基于这个快照来读,别人提交了新数据你也看不到。
  • Gap Lock(间隙锁):锁定索引记录之间的空隙,阻止其他事务在范围内插入新行。

但有一点需要特别留意:​DML语句(UPDATE/DELETE)不遵循快照读​,它们可能会看到其他事务刚提交的行。所以在某些边缘场景下,RR级别仍然有可能出现幻读。

MySQL vs PostgreSQL:默认隔离级别为什么不同?

这是一个容易被忽略,但非常重要的差异。

  • MySQL InnoDB默认使用REPEATABLE READ(RR)
  • PostgreSQL默认使用READ COMMITTED(RC)

为什么?答案在于两者MVCC的实现机制不同:

对比维度 MySQL InnoDB(RR) PostgreSQL(RC)
快照时机 事务开始时拍一次快照 每条SELECT重新生成快照
不可重复读 避免 RC级别会出现
幻读 基本避免(MVCC+间隙锁) RC级别会出现
适用场景 高并发CRUD 复杂查询、数据分析

MySQL选择RR作为默认级别,是为了在并发性能和数据一致性之间取得一个较好的平衡,适合绝大多数互联网业务场景。PostgreSQL选择RC作为默认,则是因为它在RR级别下对幻读的处理更加严格,反而可能导致更多的死锁问题。

业务场景中怎么选隔离级别?

业务场景 推荐级别 理由
金融账务、库存扣减 SERIALIZABLE 或 RR 数据一致性要求极高,不容有失
电商订单、用户中心 RR(MySQL默认) 平衡性能与一致性,典型适用场景
报表查询、数据分析 RC 以查询为主,可接受不可重复读
高并发日志写入 RC 或 READ UNCOMMITTED 写入为主,对一致性要求低

一条核心的选型原则是:不是隔离级别越高就越好。隔离级别越高,并发性能越低。你需要根据业务对一致性和性能的实际要求来做权衡。

实战避坑:两个常见的隔离级别陷阱

陷阱1:在RC级别下做“先查后改”

很多业务逻辑都是“先查询状态,再根据状态做更新”。在RC级别下,两次查询之间数据可能被其他事务修改,导致“查的时候是A,改的时候已经变成B了”——数据就这样被“吞”掉了。解决方案:要么使用RR级别,要么在查询时加上FOR UPDATE把数据锁住。

陷阱2:RR级别下的间隙锁导致死锁

RR级别通过间隙锁成功避免了幻读,但间隙锁本身也是死锁的常见来源。在RR级别下做范围删除或范围更新,很可能锁住大量不存在的“间隙”,导致多个事务互相等待,最终形成死锁。如果你的业务场景不需要防止幻读,不妨考虑降级到RC级别,牺牲一点一致性来换取更高的并发性能。

总结

事务隔离级别是数据库并发控制的核心机制,直接影响数据的正确性和系统的吞吐量。透彻理解脏读、不可重复读、幻读的本质差异,搞清楚MySQL为什么选择RR、PostgreSQL为什么选择RC作为默认值,你就能在实际业务场景中做出更合理的选择,写出更可靠、更高效的事务代码。

热点追踪提示词
你是一名 AI 行业编辑,请围绕下面这条热点输出一份资讯解读:
热点:事务隔离级别选错导致数据被吞 脏读幻读一次讲透要求:
1. 先用一句话解释这条热点在讲什么
2. 再总结它为什么重要
3. 说明会影响哪些 AI 产品或内容方向
4. 最后给出 3 个适合资讯站使用的标题
来源:https://developer.aliyun.com/article/1743306
SQL

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

相关热点
AI热点2026-07-14 19:48
面壁智能CTO谈端侧AI:从打字机到大模型的进化突围

面壁智能聚焦端侧AI,不拼参数大小,而是通过知识密度提升与模型风洞技术,将大模型压缩至手机、汽车等设备。其MiniCPM以2B参数超越同期8B对手。CTO曾国洋22岁主导训练中国首个大语言模型CPM-1。端侧AI追求“默契系统”,在用户开口前预判需求,已在吉利、上汽大众等车型落地应用。

AI热点2026-07-14 19:48
印度IT巨头HCL Tech投350亿卢比建50MW AI数据中心

印度IT巨头HCLTech投资最高350亿卢比建设AI数据中心,容量可扩展至50MW,提供从设计到运营的端到端服务,旨在满足政府及企业日益增长的算力需求,抢占印度快速增长的数据中心市场,并推动AI基础设施布局。

AI热点2026-07-14 19:48
小米具身智能机器人新工站双侧螺母上件成功率达98%

小米具身机器人在汽车工厂自攻螺母上件工站实现双侧作业成功率98%,接近人工水平。同时在新工站分别达到90%成功率,从单一操作拓展至多工站协同,验证了具身智能在复杂工业环境的落地能力。

AI热点2026-07-14 19:48
DeepSeek梁文锋身价360亿美元成AI新首富

全球AI行业正迎来新的财富格局,DeepSeek创始人梁文锋凭借其公司的迅猛发展,个人财富急剧膨胀,一举超越多位硅谷知名人物,成为全球AI公司领域的新首富。以下将详细解析其身价飙升背后的关键因素及公司发展历程。 一、身价飙升至360亿美元,超越多位AI大佬 根据最新彭博亿万富豪指数,DeepSeek

延伸阅读