【MySQL】快速理解脏读、不可重复读、幻读

news/2025/2/24 2:58:47

数据库事务的并发控制是保障数据一致性的核心机制,而脏读(Dirty Read)、不可重复读(Non-repeatable Read)和幻读(Phantom Read)是事务隔离级别设计中需要解决的三大典型问题。理解它们的区别与关联,是掌握事务隔离机制的关键。


一、脏读(Dirty Read):读到未提交的“脏数据”

定义
脏读指一个事务读取到另一个事务未提交的修改数据,若后者发生回滚,前者读取的数据即为无效的“脏数据”。


典型场景:
事务A修改某账户余额为3000元(未提交),事务B此时读取到余额为3000元。若事务A因错误回滚,账户实际余额仍为原值,但事务B已基于脏数据进行了后续操作。

时间顺序

事务 A

事务 B

1

事务开始

2

事务开始

3

查询此时账户余额 1000 元

4

充值 2000 元,使当前余额为 3000 元

5

查询此时账户余额为 3000 元(产生脏读)

6

此时业务异常导致事务回滚,余额变为 1000 元

7

消费 1000 元,此时将余额修改为 2000 元

8

提交事务

结果

正常余额应该为 0 元,但是因产生了脏读,导致事务 B 读取到了事务 A 未提交的数据,因此最后剩余 2000 元

如果在时间节点 7 上消费了 3000 元,那岂不是白嫖 2000 元。什么?为什么是 2000 元?你好好想一想

大任浅说~

如同两人同时写一本“正经”小说,A在草稿中加入了 yellow 的场景进行 YY 但未保存。

B直接读取草稿对其他章节也进行了修改,此时因为产生了脏读,导致草稿里加入 yellow 的部分。

A 觉得这样不好,肯定会被抓到小黑屋的,于是最终放弃修改。

B 却不知道 A 还有这癖好,于是看也不看就提交保存了。

结果,悲催了!两人都被抓进了小黑屋


二、不可重复读(Non-repeatable Read):同一数据前后不一致

定义
同一事务内多次读取同一条数据,因其他事务的修改或删除导致结果不一致。


典型场景:
事务A第一次查询用户金额为 3000 元,事务B将余额更新为 1000 元并提交。事务A再次查询时发现金额变为 1000 元,导致逻辑矛盾。

时间顺序

事务 A

事务 B

1

事务开始

2

事务开始

3

查询此时账户余额 3000 元

4

其他操作

5

消费 2000 元,使当前余额为 1000 元

6

提交事务

7

第二次查询账户余额为 1000 元

结果

按照逻辑,两次查询的账户余额应该一致。

与脏读的区别

  • 脏读:读到未提交的数据。
  • 不可重复读:读到已提交的修改数据,但事务内结果不一致。

大任浅说~

A 和 B 终于被放出来了

A 猛地一看,妈耶,这小 yellow 书这么多人看。于是连夜准备更新,看着自己的名字在书名下面一阵高兴。于是这次又编辑了一章,突然累了想休息一会,于是就去放飞了一下自己~

可是 B 一看,这么多人看,但是作者不是自己,于是心里不平衡了(凭什么我俩都进小黑屋,最后 A 赚了名气),于是在 A 编辑新章节的时候,改了书名的作者改成自己。

这时 A 放松完小 A 回来,在一看,嗯?作者怎么被改为 B 了?

于是直接顺着网线去找 B,A 和 B 打的昏天黑地的,不一会便被路人举报又抓进小黑屋了。


三、幻读(Phantom Read):数据行“凭空出现”

定义
同一事务内多次按相同条件查询,因其他事务的新增或删除操作导致结果集变化。这个时候事务读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,称为幻读。


典型场景:
事务A统计用户表共100条记录,事务B插入10条新记录并提交。事务A再次统计时发现记录数变为110条,如同产生“幻觉”。

时间顺序

事务 A

事务 B

1

事务开始

2

事务开始

3

查询此时数据量为 100 条

4

其他操作

5

插入一条数据

6

提交事务

7

第二次查询,数据总量为 101 条

结果

按照正确逻辑,事务A前后两次读取到的数据总量应该一致

与不可重复读的区别

  • 不可重复读:针对单条数据的修改冲突。
  • 幻读:针对结果集范围的新增或删除冲突,表现为行数增减或新行出现

大任浅说~

经过 7 天的思想教育,A 和 B 又一次从小黑屋放出来了。

这次 A 对 B 说:"老 B,这次咱俩分道扬镳吧,我忘了有多少章了,咱回去查一下按照章节数量把稿费分一下吧,一章给你 100 元,够意思吧",B 心想:"你才老 B,反正你也不知道多少章,到时候我在草稿里随便编几章,多赚点"。

等 B 走了,A 拿起手机默默地打开编辑器,一看,嗯,100 章,那就给 B10000 元吧。

此时 B 回到家赶紧用 deepseek 生成十个章节,并且保存。连忙告诉 A,“老 A 啊,你看下 110 章,你就给 11000 就行”,A 一看消息,连忙看了一下编辑器,果然是 110 章,“md,这老 B 敢黑我!”

注:编辑器为事务,章节 or 书名作者为一条数据


http://www.niftyadmin.cn/n/5863937.html

相关文章

RoCBert:具有多模态对比预训练的健壮中文BERT

摘要 大规模预训练语言模型在自然语言处理(NLP)任务上取得了最新的最优结果(SOTA)。然而,这些模型容易受到对抗攻击的影响,尤其是对于表意文字语言(如中文)。 在本研究中&#xff0…

LangChain-基础(prompts、序列化、流式输出、自定义输出)

LangChain-基础 我们现在使用的大模型训练数据都是基于历史数据训练出来的,它们都无法处理一些实时性的问题或者一些在训练时为训练到的一些问题,解决这个问题有2种解决方案 基于现有的大模型上进行微调,使得它能适应这些问题(本…

Spring MVC 与 Spring Boot:从“手动挡”到“自动驾驶”的进化论,兼谈前后端分离的哲学

引言:当“造轮子”成为一门艺术 在 Java 开发者的世界里,Spring 框架就像空气一样无处不在。但你是否想过:为什么我们需要 Spring Boot?为什么在“前后端分离”大行其道的今天,Spring MVC 依然活跃在舞台上&#xff1…

伦敦金库彻底断供的连锁反应推演(截至2025年02月22日)

‌当前背景‌:伦敦金库黄金库存仅剩‌147吨‌(为正常水平的1.8%),瑞士精炼厂交付延迟超8周,纽约COMEX黄金库存/未平仓合约比突破‌1:105‌(警戒阈值1:50)。若伦敦金库彻底断供,将触发…

【PostgreSQL】如何通过调整PostgreSQL配置参数提高数据库性能

如何通过调整PostgreSQL配置参数提高数据库性能 1. 数据库初始性能2. 内存相关参数3. WAL(Write-Ahead Logging)相关参数4. 并行查询相关参数5. 连接相关参数6. 根据情况调整 1. 数据库初始性能 使用pgbench在更新PostgreSQL数据库配置前先测试下数据库…

算法与数据结构(环形链表)

题目 思路 方法一:哈希表 我们可以这样想,若目标是环形链表,我们就会不断地在里面循环,若不是,最后肯定会遍历到nullpter。 我们可以遍历链表的所有节点,每当遍历到一个节点时,我们可以判断此…

【深度学习】Unet的基础介绍

U-Net是一种用于图像分割的深度学习模型,特别适合医学影像和其他需要分割细节的任务。如图: Unet论文原文 为什么叫U-Net? U-Net的结构像字母“U”,所以得名。它的结构由两个主要部分组成: 下采样(编码…

深度学习学习笔记(34周)

目录 摘要 Abstracts 简介 Hourglass Module(Hourglass 模块) 网络结构 Intermediate Supervision(中间监督) 训练过程细节 评测结果 摘要 本周阅读了《Stacked Hourglass Networks for Human Pose Estimation》&#xf…