温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

数据库为何发生脏读

发布时间:2026-10-31 09:54:17 来源:亿速云 阅读:89 作者:小樊 栏目:数据库

脏读(Dirty Read)是指一个事务读到了另一个尚未提交的事务修改过的数据。数据库发生脏读,通常是因为事务隔离级别设置得过低以及并发控制机制未阻止未提交数据的可见性。

下面从原因、机制和场景几个层面说明:


一、根本原因:事务隔离级别过低

数据库事务通常有四种隔离级别(以 SQL 标准为例):

隔离级别 是否允许脏读
读未提交(Read Uncommitted) ✅ 允许
读已提交(Read Committed) ❌ 不允许
可重复读(Repeatable Read) ❌ 不允许
串行化(Serializable) ❌ 不允许

脏读只会发生在“读未提交”隔离级别下。


二、技术机制原因

在“读未提交”级别下:

  • 数据库不会对未提交的数据加读锁
  • 一个事务的写操作即使没提交,其修改也会直接写入数据页或缓冲区
  • 其他事务在读取时,不会等待写事务提交,直接读到这些中间状态

因此:

事务 A 改了数据但没提交
事务 B 读了这批数据
事务 A 回滚
→ 事务 B 读到了“根本不存在的数据”


三、典型脏读示例

事务 A:
UPDATE account SET balance = 0 WHERE id = 1;  -- 未提交

事务 B:
SELECT balance FROM account WHERE id = 1;     -- 读到 0

事务 A:
ROLLBACK;  -- 回滚,余额恢复为 100

结果:

  • 事务 B 基于错误的 0 做了决策
  • 这就是脏读

四、为什么数据库允许脏读?

主要原因:

  • 性能更高:不加锁、不等待
  • 某些场景(如统计、监控)可以容忍不准确数据
  • 明确由开发者选择风险与性能的平衡

五、如何避免脏读

  1. 提高隔离级别
    SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
    
  2. 使用数据库默认隔离级别(多数默认是读已提交或可重复读)
  3. 避免手动设置 Read Uncommitted

如果你愿意,我也可以:

  • 用 MySQL / Oracle / PostgreSQL 具体举例
  • 讲 脏读 vs 不可重复读 vs 幻读 的区别
  • 结合 MVCC(多版本并发控制) 解释为什么不会脏读
向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI
助
手