sql怎么读_大白话讲解脏写、脏读、不可重复读和幻读

faac8c57a8e47013f41bf26785fedd09.png

一般对于我们的业务系统去访问数据库而言,它往往是多个线程并发执行多个事务的,对于数据库而言,它会有多个事务同时执行,可能这多个事务还会同时更新和查询同一条数据,所以这里会有一些问题需要数据库来解决

我们来看看,如果多个事务要是对缓存里的同一条数据同时进行更新或者查询,此时会产生哪些问题呢?这里实际上会涉及到脏写、脏读、不可重复读、幻读四种问题。

脏写

脏写,意思是说有两个事务,事务 A 和事务 B 同时在更新一条数据,事务 A 先把它更新为 A 值,事务 B 紧接着就把它更新为 B 值。如图:

cb831fbb037b23ad32ad2cb13f12f7d0.png

可以看到,此时事务 B 是后更新那行数据的值,所以此时那行数据的值是 B。而且此时事务 A 更新之后会记录一条 undo log 日志。因为事务 A 是先更新的,它在更新之前,这行数据的值为 NULL。所以此时事务 A 的 undo log 日志大概就是:更新之前这行数据的值为 NULL,主键为 XX

那么此时事务 B 更新完数据的值为 B,此时事务 A 突然回滚了,就会用它的 undo log 日志去回滚。此时事务 A 一回滚,直接就会把那行数据的值更新回 NULL 值。如图:

953acb75ab4d32f8ebbf0b6578eba4d2.png

然后就尴尬了,事务 B 一看,为什么我更新的 B 值没了?就因为你事务 A 反悔了把数据值回滚成 NULL 了,结果我更新的 B 值也不见 了。所以对于事务 B 看到的场景而言,就是自己明明更新了,结果值却没了,这就是脏写。

所谓脏写,就是我刚才明明写了一个数据值,结果过了一会却没了。而它的本质就是事务 B 去修改了事务 A 修改过的值,但是此时事务 A 还没提交,所以事务 A 随时会回滚,导致事务 B 修改的值也没了,这就是脏写的定义。

脏读

假设事务 A 更新了一行数据的值为 A 值,此时事务 B 去查询了一下这行数据的值,看到的值是 A 值,如图:

e2fa7398f16b185741ca08f8286654e4.png

接着,事务 B 拿着刚才查询到的 A 值做各种业务处理。但是接着坑爹的事情发生了,事务 A 突然回滚了事务,导致它刚才功能的 A 值没了,此时那行数据的值回滚为 NULL 值。然后事务 B 紧接着此时再次查询那行数据的值,看到的居然是 NULL 值。如图:

4cf044497fbec588f3e009b735695db3.png

这就是脏读。它的本质是事务 B 去查询了事务 A 修改过的数据,但是此时事务 A 还没提交,所以事务 A 随时会回滚导致事务 B 再次查询就读不到刚才事务 A 修改的数据了,这就是脏读。

其实总结一句话,无论是脏写还是脏读,都是因为一个事务去更新或者查询了另外一个还没提交的事务更新过的数据。因为另外一个事务还没提交,所以它随时可能会回滚,那么必然导致你更新的数据就没了,或者你之前查询到的数据就没了,这就是脏写和脏读两种场景。

不可重复读

假设我们有一个事务 A 开启了,在这个事务 A 里会多次对一条数据进行查询。然后呢,另外有两个事务,一个是事务 B,一个是事务 C,他们两都是对一条数据进行更新的。然后我们假设一个前提,就是比如说事务 B 更新之后,如果还没提交,那么事务 A 是读不到的,必须要事务 B 提交之后,它修改的值才能被事务 A 读取到,其实这种情况下,就是我们首先避免了脏读的发生

因为脏读的意思就是事务 A 可以读到事务 B 修改过还没提交的数据,此时事务 B 一旦回滚,事务 A 再次读就读不到了,那么此时就会发生脏读问题。我们现在假设的前提是事务 A 只能在事务 B 提交之后读取到它修改的数据,所以此时必然是不会发生脏读的

但是,此时会有另外一个问题,叫做不可重复读。假设缓存页里一条数据原来的值是 A 值,此时事务 A 开启之后,第一次查询这条数据,读取到的就是 A 值。如图:

e212d2955cbccb5fcae1208129ca57d6.png

接着事务 B 更新了那行数据的值为 B 值,同时事务 B 立马提交了,然后事务 A 此时还没提交。大家注意,此时事务 A 是没提交的,它在事务执行期间第二次查询数据,此时查到的是事务 B 修改过的值,B 值,因为事务 B 已经提交了,所以事务 A 是可以读到的,如图:

2f50e4594f6c1bbb6bebfc1ca50fe171.png

紧接着事务 C 再次更新数据为 C 值,并且提交事务了,此时事务 A 在还没提交的情况下,第三次查询数据,查到的值为 C 值,如下:

2b98621fb2b1e6b41b575f087d8d5a1d.png

那么上面的场景有什么问题呢?其实要说没问题也可以是没问题的,毕竟事务 B 和 事务 C 都提交之后,事务 A 多次查询查到它们修改的值,是 OK 的。但是你要说有问题,也可以是有问题的,就是事务 A 可能第一次查询到 A 值,那么它可能希望的是在事务执行期间,如果多次查询数据,都是同样的一个 A 值,它希望这个 A 值是它重复读取的时候一直可以读到的。它希望这行数据的值是可重复读的

但是此时,明显 A 值是不可重复读的。因为事务 B 和事务 C 一旦更新值并且提交了,事务 A 会读到别的值,所以此时这行数据的值是不可重复读的。此时对于你来说,这个不可重复读的场景,就是一种问题

上面描述的,其实就是不可重复读的问题,其实这个问题你说是问题也不一定就是什么大问题。因为这取决于你自己想要数据库是什么样子的,如果你希望看到的场景是不可重复读,也就是事务 A 在执行期间多次查询一条数据,每次都可以查到其它已经提交的事务修改过的值,那么就是不可重复读,如果你希望这样子,那也没问题。

如果你期望的是可重复读,但是数据库表现的是不可重复读,让你事务 A 执行期间多次查到的值都不一样,都的问题是别的提交过的事务修改过的,那么此时你就可以认为,数据库有问题,这个问题就是「不可重复读」

幻读

脏写、脏读和不可重复读都分别代表了不同的数据库问题。脏写就是两个事务没提交的状况下,都修改同一条数据,结果一个事务回滚了,把另外一个事务修改的值也撤销了,所谓脏写就是两个事务没提交状态下修改同一个值。

脏读就是一个事务修改了一条数据的值,结果还没提交呢,另外一个事务就读到了你修改的值,然后你回滚了,人家事务再次读,就读不到了,即人家事务读到了你修改之后还没提交的值,这就是脏读了。而不可重复读,针对的是已经提交的事务修改的值,被你事务给读到了,你事务内多次查询,多次读到的是别的已经提交的事务修改过的值,这就导致不可重复读。

接着我们说说幻读。简单来说,你一个事务 A,先发送一条 SQL 语句,里面有一个条件,要查询一批数据出来,如 SELECT * FROM table WHERE id > 10。然后呢,它一开始查询出来了 10 条数据。接着这个时候,别的事务 B往表里插了几条数据,而且事务 B 还提交了,此时多了几行数据。如图:

ed376d8318cfb85e8221e2e2c76a0d40.png

接着事务 A 此时第二次查询,再次按照之前的一模一样的条件执行 SELECT * FROM table WHERE id > 10 这条 SQL 语句,由于其他事务插入了几条数据,导致这次它查询出来了 12 条数据。如图:

d4ce847300af61ed45808b791d9dc3b9.png

于是事务 A 开始怀疑自己的眼镜了,为什么一模一样的 SQL 语句,第一次查询是 10 条数据,第二次查询是 12 条数据?难道刚才出现幻觉了?这就是「幻读」这个名词的由来

幻读就是你一个事务用一样的 SQL 多次查询,结果每次查询都会发现查到一些之前没看到过的数据。注意,幻读特指的是你查询到了之前查询没看到过的数据。此时说明你是幻读了

其实,脏写、脏读、不可重复读、幻读,都是因为业务系统会多线程并发执行,每个线程可能都会开启一个事务,每个事务都会执行增删改查操作。然后数据库会并发执行多个事务,多个事务可能会并发地对缓存页里的同一批数据进行增删改查操作,于是这个并发增删改查同一批数据的问题,可能就会导致我们说的脏写、脏读、不可重复读、幻读这些问题。

所以这些问题的本质,都是数据库的多事务并发问题,那么为了解决多事务并发问题,数据库才设计了事务隔离机制、MVCC 多版本隔离机制、锁机制,用一整套机制来解决多事务并发问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/433988.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android上试用Linphone(Free SIP VOIP Client)

1. 下载Linphone apk并且安装到两个Android手机上http://www.linphone.org/eng/download/packages/android.html2. 申请两个免费的SIP帐号进行测试https://www.ekiga.net/3. 在每个Android手机上分别配置Linphone应用程序点击Settings菜单, 在SIP Account界面分别配置如下:User…

debian 升级linux内核,Debian8升级内核到4.5

本文讲述如何升级Debian8的内核到4.5版本0x01:去linux kernel官网https://www.kernel.org/下载4.5的内核,选择tar.xz格式0x02:想办法把下载好的包弄进你的虚拟机或...直接你的物理机0x03:解压有的朋友可能没见过tar.xz格式的包&am…

软件安全测试报告模板_软件测试工程师经典面试题

软件测试工程师,和开发工程师相比起来,虽然前期可能不会太深,但是涉及的面还是比较广的。前期面试实习生或者一年左右的岗位,问的也主要是一些基础性的问题比较多。涉及的知识主要有MySQL数据库的使用、Linux操作系统的使用、软件…

OD使用教程20 - 调试篇20

OD使用教程20 - 调试篇20 让编程改变世界 Change the world by program 名词注释:Keygen为Key Generator的缩写,就是我们一般所说的注册机。是软件注册生成所需的注册码或序列号的程序。 keygen可以独立做一个可执行程序存在,也可以作为程序…

堡垒机 请确认是否安装oracle客户端_OracleOracle数据库的安装(超详细)

一、Oracle的安装对于新手来说安装Oracle这样的数据库,第一次还是会有些陌生的,我自己在安装的过程中也是遇到的很多的坑。(自己装了5遍 /(ㄒoㄒ)/~~ )由于我自己安装的是11g这个版本,所以下面以11g的下载安装为例1.下载Oracle数据库是有免费…

linux编译器项目,编译器架构 LLVM

LLVM 是 Low Level Virtual Machine (低级虚拟机)的简称,这个库提供了与编译器相关的支持,可以作为多种语言编译器的后台来使用。能够进行程序语言的编译期优化、链接优化、在线编译优化、代码生成。LLVM的项目是一个模块化和可重复使用的编译器和工具技…

卡巴斯基安全浏览器_卡巴斯基杀毒软件被曝出用户上网痕迹泄露漏洞

近期,国外安全研究人员曝出卡巴斯基杀毒软件的脚本中存在一个独特而唯一的标识符,可导致用户在过去4年中访问过的每个网站都被泄露。该漏洞被标记为CVE-2019-8286,其中所涉及的独特标识可让被访问过的网站和第三方商业公司在线跟踪用户。更严…

栅格矢量化_学会用栅格系统,普通LOGO秒变高大上

经常看到很多 LOGO 初看一般,但只要加上了栅格线,感觉瞬间就上了一个档次。有个比较出名的例子,就是锤子手机的 LOGO。是不是觉得右边的栅格线加上之后,瞬间高大上了许多?那这些栅格线真的只能拿来展示吗?有…

移动端怎么让底部固定_移动端排名应该怎么做?两种匹配移动端实战排名干货分享!...

关于移动端优化的问题、最近一些兄弟一直在问我应该怎么做?毕竟现在是手机的时代、绝大部分情况下、PC显得有点鸡肋!在讲移动端排名之前、逆冬先来讲两个容易被大家搞错的问题(移动端)。1、我观察现在的移动端都是独立的http://m.xxx.com,是不是百度喜欢独立的移动…

Linux绘图函数与驱动,Linux中与驱动相关的ioctl函数

一: ioctl函数的作用ioctl用于向设备发控制和配置命令 ,有些命令也需要读写一些数据,但这些数据是不能用read/write读写的,称为Out-of-band数据。也就是说,read/write读写的数据是in-band数据,是I/O操作的主体&…

给管道注册事件,用于用户是否登录!

1.一个网站项目的自定义cs文件,如图: 2.CheckRight.cs中的代码如下: public class CheckRight : IHttpModule{ public void Dispose() { } public void Init(HttpApplication app) { app.AcquireRequestState new EventHandler(app_AcquireR…

css 商城 两列_【云控基础】HTML+CSS基础入门

课程大纲:第一部分:课程概述1、什么是HTML、CSS,能做什么?2、HTML、HTML5、H5的区别3、HTMLCSS全览4、HTML、CSS的学习路径和学习方法第二部分:HTMLCSS开发环境搭建1、谷歌浏览器的安装和简单使用2、Sublime Text 编辑…

搜索不包含关键词_亚马逊listing关键词优化

亚马逊是一个客户至上的平台,它将客户体验置于一切之上。根据亚马逊的说法,消费者找到产品的速度越快,他们的购物体验就会越好。因此,亚马逊的A9算法被设计用来寻找对客户购物体验有价值的相关listing。如果你想提高你的搜索排名&…

excel文件损坏修复绝招_高手都在用的PDF转换PPT、WORD、EXCEL工具

点击上方关注我,UUUhooo,你最好了……首先说标题提到转换是在格式间转换,而不是软件间转换,所以标题是为了大多数人认知方便而起的,PDF是一种文档格式,全程叫便携式文档格式,而打开它的软件叫PD…

cowboy源码分析

2013-01-21 by 谢鸿锋   原创文章,转载请注明:转载自Erlang云中漫步 目录 一、概述 二、ranch源码分析 三、cowboy源码分析 1、Request调度规则 2、http协议实现分析 3、http协议之chunked编码 4、http协议之long_polling 5、http协议之websocket 6、…

linux解压tz zip,TZ 文件扩展名: 它是什么以及如何打开它?

TZ 疑难解答常见的 TZ 打开问题Smith Micro StuffIt Deluxe 已删除尝试打开 TZ 文件时,您收到错误 “无法打开 TZ 文件类型”。 发生这种情况时,通常是由于 %%os%% 中缺少 Smith Micro StuffIt Deluxe。 操作系统不知道如何处理你的 TZ 文件,…

无法定位程序输入点 except_软件测试中的功能测试点(三)

testkuaibao|软件测试自学公众号26.输入法半角全角检查再输入信息中,输入一个或连串空格,查看系统如何处理,如对于要求输入符点型数据的项中,输入全角的小数点(“。”或“.”,如4.5);输入全角的空格等。 27…

ASP.NET站点跨子域名单点登陆(SSO)的实现

http://blog.csdn.net/jason_dct/article/details/8502075 ASP.NET站点跨子域名单点登陆(SSO)的实现 在MSDN的文档“配置跨应用程序的 Forms 身份验证(http://msdn2.microsoft.com/zh-CN/library/eb0zx8fc.aspx)” 中,…

linux实验三makefile,实验平台上Makefile详细的解释

作者:甘老师,华清远见嵌入式学院讲师。# CORTEX-A8 PERI DRIVER CODE# VERSION 2.0# ATHUOR www.linuxidc.com# MODIFY DATE#2013.03.28 Makefile/***(下面的解释将用这个的形式进行标注)写好的源文件,要编译成二进制文件.需要指定工具链的,这里指定我们的工具链是…

基础C#总结

由于在学习c#这段视频是为了辅助设计模式的学习,这部分的内容也和VB的内容很大程度上是一样的.虽然在开始的 时候,有些困难.在接触了一些例子和实验后.理解起来变得顺畅了很多.下面是对c#基础内容的总结.很多内容都在VB中有 过接触,所以都是些基础知识.捋一捋,将这些时间脑子的…