并发事务引入的问题:幻读、不可重复读、脏读

总结

整理了并发 事务 时会出现的幻读、不可重复读、脏读问题。

详情

概念

现象 定义简述
幻读(Phantom Read) 同一个事务内多次查询某一范围的记录,结果数量变化,出现“幻行”。
不可重复读(Non-Repeatable Read) 同一个事务内多次读取同一数据,结果不一致。
脏读(Dirty Read) 一个事务读取了另一个事务未提交的数据。

幻读举例说明

事务 A 在读取某个范围内的记录时,事务 B 又在该范围内插入了新的记录,事务 A 再次读取该范围的记录时,会产生幻行(Phantom Row)。

假设有 A 和 B 这两个事务同时在处理:

  • 事务 A 查询符合要求的记录,发现共有 3 条;
  • 事务 B 插入了 2 条新纪录并提交事务;
  • 事务 A 再次查询记录,此时查询到的记录数有 5 条

前后两次记录数不一致,这就是幻读。

不可重复读举例说明

假设有 A 和 B 这两个事务同时在处理:

  • 事务 A 查询账户余额,然后继续执行代码;
  • 事务 B 更新了账户余额并提交事务;
  • 事务 A 再次查询账户余额,此时账户余额变了。

前后两次读取的数据不一致,这种现象就被称为不可重复读。

脏读举例说明

假设有 A 和 B 这两个事务同时在处理:

  • 事务 A 更新账户余额,但还没有提交事务
  • 事务 B 读取账户余额,
    事务 B 读取的是事务 A 修改后未提交事务的数据,发生了脏读。

事务 A 还没提交事务,随时可能发生回滚操作,如果事务 A 发生了回滚,那么事务 B 读取的数据就是不正确的。

对比

对比维度 幻读 不可重复读 脏读
发生对象 查询结果集(多行集合) 数据项(某一行某个字段) 数据项(如某一行某个字段)
操作类型 插入或删除导致记录数变化 读取已提交的修改 读取未提交的修改
是否涉及新增/删除记录
是否违反一致性 影响一致性(逻辑错误) 部分违反一致性 严重违反一致性(读到无效数据)
举例 A 两次查询记录,B 插入了两条 A 两次查余额,B 中间更新了它 B 读 A 未提交的余额修改
严重程度 较轻 中等 最严重

三个现象的严重性排序如下:脏读>不可重复读>幻读

关联文章


文章作者: huan
版权声明: 本博客所有文章除特別声明外,均采用 CC BY-NC-ND 4.0 许可协议。转载请注明来源 huan !
  目录