快速理解脏读,不可重复读,幻读

什么是脏读、不可重复读和幻读?产生原因是什么?有什么解决办法? 文章结合示例介绍了脏读、不可重复读、幻读的出现原因和影响,并引入拓展了MVCC、当前读、快照读、间隙锁等概念,通俗易懂 阅读详情

介绍

要聊事务,不可避免的要提到数据库事务的四大特性:ACID

  • atomic
  • consistence
  • isolation
  • durability

先放一个表格,看看4个隔离级别会出现的各种问题,网上的解释一大堆。看完后还是一脸懵逼,感觉懂了,又好像没懂。因为没有具体的演示例子,索性自己尝试复现这几个问题。

√ 为会发生,×为不会发生:

隔离级别脏读不可重复读幻读
read uncommitted(未提交读)√√√
read committed(提交读)×√√
repeatable read(可重复读)××√
serialization(可串行化)×××

再总结mysql 的常用命令(下面会用到):

命令含义
select version()查看MySQL版本
SELECT @@tx_isolation查看MySQL隔离级别
set session transaction isolation level 隔离级别会话层面设置隔离级别
start transaction开启事务
commit提交事务
rollback回滚事务

演示

首先建立如下表:

CREATE TABLE `account` (
 `id` int(2) NOT NULL AUTO_INCREMENT,
 `name` varchar(10) DEFAULT NULL,
 `balance` int(3) DEFAULT '0',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

用Navicat(其他工具也行)开2个查询的tab页,表示2个会话
在这里插入图片描述

首先,在2个Tab页面分别执行SELECT @@tx_isolation,输出都是REPEATABLE-READ,表明MySQL默认隔离级别为REPEATABLE-READ(可重复)读。

*脏读

表中的数据如下,设置隔离级别为未提交读
在这里插入图片描述

时间客户端A客户端B
T1set session transaction isolation level read uncommitted;
start transaction(开启事务);
update account set balance = balance+1000 where id = 1;
select * from account where id = 1;
设置为未提交读,给张三账号+1000,输出为2000
T2set session transaction isolation level read uncommitted;
start transaction;
select * from account where id = 1;
查询余额输出为2000
T3rollback
T4commit
T5select * from account where id = 1;
查询余额输出为1000

----->举个例子概述一下这个过程,财务给张三发了1000元的工资,然后张三查询自己的账户,果然多了1000元,变成了2000元,结果财务操作过程有误,事务回滚。当张三再查账户时,却发现账户只有1000元。

脏读就是指当事务A对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务B也访问这个数据,然后使用了这个数据。

----->再举一例,表中的数据如下:
在这里插入图片描述

时间客户端A客户端B
T1set session transaction isolation level read uncommitted;
start transaction;
update account set balance = balance-1000 where id = 1;
update account set balance = balance+1000 where id = 2;
T2set session transaction isolation level read uncommitted;
start transaction;
select balance from account where id = 2;
update account set balance = balance -1000 where id = 2;
更新语句被阻塞
T3rollback
T4commit

执行完成,数据库中的数据如下
在这里插入图片描述
解释如下:

时间解释
T11给2转账1000
T22的余额够1000,购买1000元商品,更新语句被阻塞
T31回滚,1的余额变成1000,2的余额变成0
T42成功扣款,余额为0-1000=-1000

如此便出故障了!

*不可重复读

表中的数据如下,设置隔离级别为提交读
在这里插入图片描述

时间客户端A客户端B
T1set session transaction isolation level read committed;
start transaction;
select * from account where id = 2;
查询出余额输出为0;
T2set session transaction isolation level read committed;
start transaction;
update account set balance = balance + 1000 where id = 2;
select * from account where id = 2;
commit;
查询余额输出1000
T3select * from account where id = 2;
commit;
查询余额输出1000

不可重复读是指在事务1内,读取了一个数据,事务1还没有结束时,事务2也访问了这个数据,修改了这个数据,并提交。紧接着,事务1又读这个数据。由于事务2的修改,那么事务1两次读到的的数据可能是不一样的,因此称为是不可重复读。

当然你可以在T2时间段客户端B修改完id=2的账户余额但没有commit的时候,在客户端A查询id=2的账户余额,发现账户余额为0,可以证明提交读这个隔离级别不会发生脏读。

现在用上面的例子看一下可重复读是个什么过程?

表中的数据如下,设置隔离级别为可重复读
在这里插入图片描述

时间客户端A客户端B
T1set session transaction isolation level repeatable read;
start transaction;
select * from account where id = 2;
查询余额输出为0;
T2set session transaction isolation level repeatable read;
start transaction;
update account set balance = balance + 1000 where id = 2;
select * from account where id = 2;
commit;
查询余额输出1000
T3select * from account where id = 2;
commit;
查询余额输出0

仔细看这个例子和上面的例子在T3时间段的输出,理解了什么叫可重复读了吧?当我们将当前会话的隔离级别设置为可重复读的时候,当前会话可以重复读,就是每次读取的结果集都相同,而不管其他事务有没有提交。
----------但是在可重复读的隔离级别上,会产生幻读的问题。

*幻读

表中的数据如下,设置隔离级别为可重复读
在这里插入图片描述
先上一段《高性能MySQL》对于幻读的解释

所谓幻读,指的是当某个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,当之前的事务再次读取该范围的记录时,会产生幻行。InnoDB存储引擎通过多版本并发控制(MVCC)解决了幻读的问题。

用大白话解释一下,就是事务1查询id<10的记录时,返回了2条记录,接着事务2插入了一条id为3的记录,并提交。接着事务1查询id<10的记录时,返回了3条记录,说好的可重复读呢?结果却多了一条数据。

MySQL通过MVCC解决了这种情况下的幻读,我们可以验证一下

时间客户端A客户端B
T1set session transaction isolation level repeatable read;
start transaction;
select count(*) from account where id <=10;
输出2;
T2set session transaction isolation level repeatable read;
start transaction;
insert into account(id,name,balance) values(“3”,“王五”,“0”) ;
select count(*) from account where id <=10;
commit;
输出3
T3select count(*) from account where id <=10;
commit;
输出2

这种情况下的幻读被解决了,再举一例,表中的数据如下
在这里插入图片描述

时间客户端A客户端B
T1set session transaction isolation level repeatable read;
start transaction;
select count(*) from account where id =3;
输出0;
T2set session transaction isolation level repeatable read;
start transaction;
insert into account(id,name,balance) values(“3”,“王五”,“0”) ;
commit;
T3insert into account(id,name,balance) values(“3”,“王五”,“0”);
;主键重复,插入失败
T4select count(*) from account where id =3;
输出0;
T5rollback;

select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,这个就有问题了。

很多人容易搞混不可重复读和幻读,确实这两者有些相似。但不可重复读重点在于update和delete,而幻读的重点在于insert。

注意:不可重复读和幻读的区别是:前者是指读到了已经提交的事务的更改数据(修改或删除),后者是指读到了其他已经提交事务的新增数据。
对于这两种问题解决采用不同的办法,防止读到更改数据,只需对操作的数据添加行级锁,防止操作中的数据发生变化;而防止读到新增数据,往往需要添加表级锁,将整张表锁定,防止新增数据(oracle采用多版本数据的方式实现)。

当隔离级别设置为可串行化,强制事务串行执行,避免了前面说的幻读的问题。

脏读、幻读、不可重复读产生的原因及解决方案 在平时操作数据库时,尤其是在并发场景下,常常会遇到一些问题,比如脏读、幻读、不可重复读,本篇我将对这几个问题产生的原因进行分析并给出解决办法 阅读详情

相关推荐

快速上手CH340N电路设计(CH340N USB转串口模块 USB Type-C接口 CH340系列芯片讲解)

一、上模块 二、功能分析 l 芯片:CH340N l 输入接口:USB、TYPE-C l 输出接口:TTL(5V\3.3V\GND\TX\RX) l 指示灯:电源、TX、RX 三、CH340x芯片 l CH340 是一个 USB 总线的转接芯片,实现 USB 转串口 l 全速 USB 设备接口,兼容 USB V2.0 l 硬件全双工串口,内置收发缓冲区,支持通讯波特率 50bps~2Mbps l 支持常用的 MODEM 联络信号 RTS、DTR、DCD、RI、DS...

东小东博客 5万+

脏读幻读和不可重复读 数据库锁 隔离机制

一、脏读、不可重复读、幻读1、脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。 例如: 张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。 与此同时, 事务B正在读取张三的工资,读取到张三的工资为8000。 随后, 事务A发生异常,而回滚了事务。张三的工资又回滚为5000。 最后, 事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。2、不可重复读:是指在一个事务内,多

song854601134的博客 6万+

【Diffusion分割】医学图像分割中去噪扩散技术

扩散模型(DPM)在图像生成方面表现出了卓越的性能,其性能往往优于其他生成模型。自其问世以来,强大的噪声-图像去噪管道已被扩展到各种判别任务中,包括图像分割。在医学成像中,图像往往是大型三维扫描图像,由于内存消耗大、迭代采样过程耗时,使用 DPM 对一幅图像进行分割的效率极低。在这项工作中,我们提出了一种(LDSeg),可在潜空间中执行扩散,用于医学影像分割。我们。潜空间条件扩散不仅能确保对多标签对象进行精确的 n-D 图像分割,还能缓解基于 DPM 的传统分割法的主要潜在问题:(。

qq_43583311的博客 1162

一文详解脏读、不可重复读、幻读

MySQL 是支持多事务并发执行的。否则来一个事务处理一个请求,处理一个人请求的时候,其它事务都等着,那估计都没人敢用MySQL作为数据库,因为用户体验太差,估计都要砸键盘了。 既然事务可以并发操作,这里就有一些问题:一个事务在写数据的时候,另一个事务要读这行数据,该怎么处理?一个事务在写数据,另一个数据也要写这行数据,又该怎么处理这个冲突? 这就是并发事务所产生的一些问题。具体来说就是:脏读、不可重复读和幻读。 一、概念说明 以下几个概念是事务隔离级别要实际解决的问题,所以需要搞清楚都是什么意思。 1、脏

weixin_41814871的博客 4万+

Windows环境下DataEase一站式安装指南(含WSL2+Docker配置)

本文详细介绍了在Windows环境下通过WSL2和Docker快速部署DataEase的完整教程。从WSL2配置、Docker环境搭建到DataEase离线安装,逐步指导用户完成一站式部署,特别适合需要快速搭建数据分析平台的开发者。教程包含常见问题解决方案和性能优化技巧,帮助用户高效使用这款国产开源数据可视化工具。

weixin_42526166的博客 379

看28377代码笔记

使用的是20MHz外部晶振,为取200MHz系统时钟,倍频设为20,分频设为2,这样sysclock = 20MHz * 20 / 2,正好200MHz。注意:SPISTE配置成普通的GPIO端口,是为了更好控制芯片,配置芯片的时序。FMULT_0:小数点位数,小数只能有0,0.25,0.5,0.75四个选择。XTAL_OSC:表示使用外部晶振。GPIO_MUX_CPU1:复用类型。GPIO_MUX_CPU1:复用类型。PLLCLK_BY_2:表示2分频。IMULT_20:表示倍频数。

小柚子的博客 800

【MySQL理论】脏读、不可重复读、幻读

文章目录1. 脏读(dirty read)脏读是指事务读取到其他事务未提交的数据2. 不可重复读(non-repeatable read)不可重复读是指在同一次事务中前后查询不一致的问题3. 幻读(phantom read)幻读是一次事务中前后数据量发生变化,用户产生不可预料的问题4. 总结5. 解决方法 1. 脏读(dirty read) 脏读是指事务读取到其他事务未提交的数据 例如:有事务A、B和一条记录:id为1,name为张三 B首先进行更新操作,将name的值由张三改为张老三,但还未提交事务 be

Hi there 1万+

matlab 基于离散余弦变换DCT的最小二乘相位解缠

最小范数法是寻求在解包裹相位的局部微分与包裹相位微分相一致的条件下, 逼近于真实相位分布的解包裹相位分布。目标是使解包裹相位与包裹相位曲面的差最小

点云侠的博客 281

快速理解脏读、不可重复读和幻读

MySQL的InnoDB引擎是支持事务的,但是并发事务的处理又会带来以下问题: 脏读 不可重复度 幻读 一、脏读 脏读指事务A读取到了事务B更新了但是未提交的数据,然后事务B由于某种错误发生回滚,那么事务A读取到的就是脏数据。 具体的说,一个数据原本是干净的,但是事务B将它进行修改使得其不再干净,此时事务A读取到事务B修改后的数据,也就是脏数据,称为脏读,后来事务B由于良心发现又将数据回滚为最初的样子,而事务A不知道事务B进行了回滚操作,最终事务A读取到的是脏数据,称为脏读。 结论:读取未提交的数据!

郑皓云的博客 8586

ABAP Cloud:面向云时代的 ABAP 开发范式与实践指南

摘要: 本文系统讲解SAP ABAP Cloud开发模型,涵盖其架构、工具链、规范及实践。ABAP Cloud作为统一开发模型,支持在SAP BTP和S/4HANA上构建云就绪应用,遵循clean core原则,通过RAP(RESTful应用编程模型)实现低耦合扩展。文章详细解析其核心构成(RAP、稳定API、clean core约束)、工具链(ADT、软件物流)及两种典型扩展场景(on-stack与side-by-side),并附可运行RAP示例代码(如销售笔记应用)。重点强调通过规范开发确保系统可升级性

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 375

Boot过程相关镜像详解:IVT、DCD、App Boot镜像到底是什么?

S32系列芯片中常说的IVT镜像、DCD镜像等跟Boot过程相关的镜像到底是什么,镜像结构长啥样?各镜像作用是什么?主分区和备份区的概念?答案统统在这里!!

车载系统攻城狮 4249

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

                             快速理解脏读、不可重复读、幻读?   理解这三种由于并发访问导致的数据读取问题,再理解事务隔离级别就简单多了。   【1】脏读(读取未提交数据) ...

iQian²的博客 167

Matlab安装硬件支持包、simulink离线安装硬件支持包安装,离线安装ESP32、stm32等安装包,Are you up-to-date on SoftWare Maintenance?

注意:如果提示出现“没有可从此位置安装的兼容支持包后,这个问题,请查看步骤5,是不是没有按照步骤5进行操作.一般情况下出现“没有可从此位置安装的兼容支持包”后,重新安装选择了默认路径就可以成功。如果不是很清楚,直接安装在默认的文件夹下面,即使这个文件夹下没有matlab相关的文件夹,也要这么下载,没有为什么,切记尽量按默认路径安装,更改下载的路径不成功,别怪我没提醒。:下载到哪里非常重要,如果下载的不是默认的路径下,就需要将其中这个的是这个archives文件夹,连同其他文件一并要复制出来,拷贝到。

pvmsmfchcs的博客 1739

快速理解脏读、不可重复读、幻读和MVCC

理解这三种由于并发访问导致的数据读取问题,再理解事务隔离级别就简单多了。脏读(读取未提交数据)A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么...

互扯程序的博客 2561

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

【数据库】快速理解脏读、不可重复读、幻读

快速理解脏读、不可重复读、幻读? 理解这三种由于并发访问导致的数据读取问题,再理解事务隔离级别就简单多了。 【1】脏读(读取未提交数据) A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个...

阳阳的博客 11万+

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

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

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

大白的成长之路 1973

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

快速理解 脏读、不可重复读、幻读(解决方法)

文章目录脏读【读取数据未提交】不可重复读【前后多次读取,数据内容不一致】幻读【前后多次读取,数据总量不一致】数据库事务隔离级别未提交读读已提交 Read Committed可重复读 Repeatable Read可串行化 Serializable 脏读【读取数据未提交】 一个事务读取另外一个事务未提交的更新事务。 事务1 事务2 select age from table1 whe...

wangrui1605的博客 1780

java 幻读 脏读_快速理解脏读、不可重复读、幻读

1、脏读 是指A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚,那么A事务读取到的数据就是脏数据,一般发生在并发或多用户操作同一数据库信息时产生的。脏读举例说明:现有A、B两位同学,A同学账户有2000元, 两位同学同时操作A账户1560499745(1).png2、不可重复读 是指A事务读取了B事务已经提交的更改数据,假如A在取款过程中,B往该账户转账100,A再次读取的余额发...

weixin_30827827的博客 908

【数据库】快速理解脏读、不可重复读、幻读?

快速理解脏读、不可重复读、幻读? 理解这三种由于并发访问导致的数据读取问题,再理解事务隔离级别就简单多了。 【1】脏读(读取未提交数据) A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个时候A事务立即读取了这个脏数据,但事务B良心发现,又用回滚把数据恢复成原来干净、纯粹的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读。 这种情况常发

zero123_的博客 176
上一篇: Netty编解码框架分析
下一篇: mysql数据备份
zhg_vincent
博客等级 码龄12年 93粉丝 45原创
评论 21
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值