再有人问你MySql的隔离级别,直接把这篇文章发给他!

作者 l zyz1992

来源 l Hollis(ID:hollischuang)

首先要明白什么是事务?

事务是程序中一系列严密的操作,所有的操作必须完成,否则在所有的操作中所做的所有的更改都会被撤销。也就是事务的原子性,一个事务中的一系列的操作要么全部成功,要么就是失败。

事务的结束有两种,当事务中所有的步骤全部成功执行的时候,事务提交。如果其中一个步骤失败,将会发生回滚操作,撤销到事务开始之前的所有的操作。

 

事务的ACID

事务具有四个特征

  1. 原子性 事务是数据库的逻辑工作单位,事务中包含多个操作,要么都做完,要么都不做

  2. 隔离性(隔离性也是本文的重点) 事务彼此之间是不能互相干扰的,即一个事务的操作对该数据库的其他事务操作是隔离的,并发执行的各个事务时间互补干扰

  3. 持久性 事务一旦提交,其变更是永久性的

  4. 一致性 事务执行的结果必须满足从一个状态变到另一个状态,因此当数据库只包含成功事务提交的结果时,就说数据库处于一致性的状态。如果数据库系统在运行时发生系统故障,有些未完成的事务被迫中止,而有一部分修改已经写入数据库,这个时候数据库就处于一种不正确的状态。

其实以上三个条件(原子性、隔离性、持久性)最终都是为了保持数据库数据的一致性服务的

MySQL的四种隔离级别

SQL标准定义了四种隔离级别,用来限定事务内外的哪些改变是可见的,哪些是不可见的。

  1. 读取未提交的数据【Read Uncommitted】 在该隔离级别,所有的事务都可以看到其他事务没有提交的执行结果。(实际生产中不可能使用这种隔离级别的)

  2. 读取提交的内容【Read Committed】 该隔离级别是大多数数据库的默认的隔离级别(不是 MySQL 默认的)。它满足了隔离的简单定义:一个事务只能看到其他的已经提交的事务所做的改变。这种隔离级别也支持不可重复读,即同一个 select 可能得到不同的结果

  3. 可重读【Repeatable Read】 这是 MySQL 默认的隔离级别,它确保同一个事务在并发读取数据时,会看到同样的数据行。不过理论上会导致另外一个问题,【幻读】。幻读:相同的条件查询一些数据,然后其他事务【新增】或者是【删除】了该条件的数据,然后导致读取的结果不一样多。InnoDB 存储引擎通过多版本控制(MVCC)机制解决了该问题

  4. 可串行化【serializable】 这是事务的最高隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决了幻读的问题。它在每个读的数据行上面加上共享锁,。但是可能会导致超时和锁竞争(这种隔离级别太极端,实际生产基本不使用)

这四种隔离级别采用不同的锁类型来实现

  1. 脏读 读取了前一个事务未提交的或者是回滚的数据

  2. 不可重复度 同样的 select 查询,但是结果不同,过程中有事务更新了原有的数据

  3. 幻读 两次查询的结果数量不一样,过程中有事务新增或者是删除数据

下面对不同的隔离级别产生的不同的问题做一个汇总

各个隔离级别的详细测

查看数据库的隔离级别

show variables like '%isolation%'

设置数据库的隔离级别

set session transaction isolation level Read Uncommitted;

设置数据库的隔离级别为:Read Uncommitted

实验一:Read Uncommitted

Read Uncommitted 即:读取未提交

前置条件:将数据库的隔离级别设置为read uncomitted;

set session transaction isolation level Read Uncommitted;

img

img

第一步:A开启事务:start tracsaction;

img

第二步:A查询数据:select * from test;

img

第三步:B开启事务:start transaction;

img

第四步:B查询数据:select * from test;

img

第五步:B更新数据:update test set num =10 where id = 1;B没有提交事务

img

第六步:A读取数据----A读取到了B未提交的数据(当前数据库的隔离级别是:Read Uncommitted

img

第七步:B回滚数据:rollback;

img

第八步:B查询数据:select * from test;

img

第九步:A查询数:select * from test;

img

结论:事务B更新了数据,但是没有提交,事务A读取到的是B未提交的记录。因为造成脏读。Read Uncommitted是最低的隔离级别

实验二:读取已提交-Read Committed

前置条件:将数据库的隔离级别设置为:Read Committed;

set session transaction isolaction level Read Committed;

img

img

第一步:A开始事务:start transaction;

img

第二步:A查询数据:select *from test;

img

第三步:B开启事务:start transaction;

img

第四步:B查询数据:select * from test;

img

第五步:B更新数据:update test set num =10 where id=1

查看结果:

img

第六步:A查询数据:select * from test;

img

第七步:B提交数据:commit;

img

第八步:A查询数据:select * from test;

img

结论:Read Committed 读已提交的隔离级别解决了脏读的问题,但是出现了不可重复读的问题,即事务A在两次查询的结果不一致,因为在两次查询之间事务B更新了一条数据。

读已提交的只允许读取已经提交的记录 ,但是不要求可重复读

实验三:可重读度-Repeatable Read

前置条件:将数据库的级别设置为可重复度

set session transaction isolation level repeatable read;

img

第一步:A开始事务:start transaction;

img

第二步:A查询数据:select * from test;

img

第三步:B开启事务:start transaction;

img

第四步:B查询数据:select * from test;

img

第五步:B更新数据:update test set num=10 where id=1;

img

此时B并没有提交事务

第六步:B查询数据:select * from test;

img

第七步:A查询数据

img

结果仍然是之前的结果(因为B事务还没有提交)

第八步:B提交事务:commit;

img

第九步:A查询数据:select * from test;此时A查询的记录仍然和之前一样

img

第十步:B插入一条数据并提交事务:inset into test(num) value(4);

img

第十一步:A查询数据,发现结果还是和之前的一样:select * from test;

img

第十二步:A提交事务并查询数据

img

此时发现A查询的数据已经和B查询的结果一致了;

结论:Repeatable Read隔离级别只允许读取已经提交的事务的记录,

实验四:串行化-Serializable

前置条件:将数据库的隔离级别设置为可串行化

img

第一步:A开始事务并查询数据

img

第二步:B开启事务并insert数据,发现只能等待,并不能执行下去

img

第三步:A提交事务

img

第四步:B插入数据

img

结论:serializable完全锁定字段,若一个事务来操作同一份数据,那么就必须等待,直到前一个事务完成并解除锁为止。是完整的隔离级别,会锁住对应的数据表,因为会导致效率问题。

本文小结

本片文章并没有深入的去讲解原理,而是让大家能够从更直观的从隔离级别的表面去了解隔离级别,因为我发现我的很多同事对此是模模糊糊,模棱两可的,但是这个是不可以的,因为技术本身是不允许存在这种歧义的,懂就是懂,才能合理运用,如果模棱两可,那么在实际运用中一定也是漏洞百出,所以这也是这篇文章诞生的原因。

我们可以先抛开原理与底层的具体实现,先能够清晰且明了的搞清楚各个专业术语的含义,这未尝不是一种进步。

最后以一句不积跬步无以至千里,不积小流无以成江河与诸君共勉!


往期推荐

厉害了,Spring中bean的12种定义方法!


@Autowired报错的4种解决方案和原因分析!


SpringBoot 中的 3 种条件装配!



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

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

相关文章

生产环境一次诡异的NPE问题,反转了4次

前言公司为了保证系统的稳定性,加了很多监控,比如:接口响应时间、cpu使用率、内存使用率、错误日志等等。如果系统出现异常情况,会邮件通知相关人员,以便于大家能在第一时间解决隐藏的系统问题。此外,我们这…

ZooKeeper学习笔记—配置管理

为什么80%的码农都做不了架构师?>>> 最近在工作中,为了完善公司集群服务的架构,提高可用性,降低运维成本,因此开始学习ZooKeeper。 至于什么是ZooKeeper?它能做什么?如何安装ZooKee…

C# Winform 窗体美化(六、双层窗体)

六、双层窗体 大概情况 双层床体是为了平滑的创建异形窗体的一个解决方案,找了很多资料,整理了一下。 双层窗体的逻辑是建立在 UpdateLayeredWindow 不能绘制控件的基础上,上层再添加一个专门放置控件的层;这样就可以在上层“控…

批处理框架 Spring Batch 这么强,你会用吗?

来源:blog.csdn.net/topdeveloperr/article/details/84337956spring batch简介Spring Batch架构介绍Spring Batch核心概念介绍chunk 处理流程批处理操作指南spring batch简介 spring batch是spring提供的一个数据处理框架。企业域中的许多应用程序需要批量处理才能在…

Android Bundle类别

即使在今天发现自己Bundle类不明确,因此,花时间去研究了一下。 依据google官方文件(http://developer.android.com/reference/android/os/Bundle.html) Bundle类是一个key-value对,“A mapping from String values to …

C# Winform 窗体美化(七、Win7 Aero 毛玻璃效果)

七、Win7 Aero 毛玻璃效果 在 Win7 上有一种 Aero 效果,毛玻璃透明效果,搭配不同风格的颜色,效果很好。在学习 Winform 美化的时候顺便看到的这种效果,也整理进来了。 注意:Win7 上想看到这种效果需要开启并使用 Aer…

非导向传输媒体| 计算机网络

Transmission media can be categorized in two ways, 传输媒体可以通过两种方式进行分类: Guided Transmission Media 引导传输媒体 Unguided Transmission Media 非引导传输媒体 1)非引导传输媒体 (1) Unguided Transmission Media) It is also called wireless …

面霸篇:MQ 的 5 大关键问题详解

最近mq越来越火,很多公司在用,很多人在用,其重要性不言而喻。但是如果我让你回答下面的这些问题:我们为什么要用mq?引入mq会多哪些问题?如何解决这些问题?你心中是否有答案了呢?本文…

C# Winform 窗体美化(八、Icon)

八、Icon 之前 Winform 项目也有在 Icon 上遇到些问题(这里的 Icon 指的是 .ico 类型的文件),比如刚开始不知道怎么让自己的程序 Icon 和其他软件一样可以放大,还有放大之后在音量合成器中会出现比较奇葩的效果之类的问题&#x…

MyBatis 的执行流程,学废了!

作者:双子孤狼来源:blog.csdn.net/zwx900102/article/details/108455514MyBatis可能很多人都一直在用,但是MyBatis的SQL执行流程可能并不是所有人都清楚了,那么既然进来了,通读本文你将收获如下:1、Mapper接…

C# Winform 窗体美化(九、嵌入窗体)

九、嵌入窗体 还是关于 Winform 窗体的一些操作问题,这次是研究了一个嵌入窗体,这次学习纯属偶然,项目中确实没遇到过这种需求。就是把别人的程序嵌入到自己的程序中,就像这样: 这里我嵌入了测试显示器的程序 [外链图…

SpringBoot 优雅的参数效验!

引言 不知道大家平时的业务开发过程中 controller 层的参数校验都是怎么写的?是否也存在下面这样的直接判断?public String add(UserVO userVO) {if(userVO.getAge() null){return "年龄不能为空";}if(userVO.getAge() > 120){return &quo…

NTFS Change Journal(USN Journal)详解

写在前面 最近又用了一下usn日志来获取所有文件列表,在分多次加载文件列表的时候发现有文件丢失的情况,后来发现一篇文章比较详细的讲了usn。 用cmd来读取usn日志 如图: 以下是转载内容: 还是那个文件监控的应用,…

绝,Java 中创建对象的 5 种方法!

我们日常生活中会创建很多对象,但是这个对象和你理解的那么对象不一样,因为作者不是女娲,不能造人。作者只是程序员,他只能在 Java 中创建对象。那么我问你一个问题,你知道 Java 中如何创建对象吗?这个问题…

C# Winform 窗体美化(十、自定义窗体)

十、自定义窗体 写在前面 最近在做 winform 应用程序,需要自定义一种窗口的样式,所以就随便搞了一个简单的窗口。 效果图 有两种样式,界面如下: 无标题: 有标题: 关键词 1、黑色描边边框 对于…

SpringBoot时间格式化的5种方法!

作者 | 王磊来源 | Java中文社群(ID:javacn666)转载请联系授权(微信ID:GG_Stone)在我们日常工作中,时间格式化是一件经常遇到的事儿,所以本文我们就来盘点一下 Spring Boot 中时间格…

C#文件加密和解密

下载 CSDN下载:https://download.csdn.net/download/myinc/9913318 Github:GitHub 如果没有积分,也可以关注我获取哟~【文件加密】 // * 最近看了一下加密算法,对加密文件突然很感兴趣,就研究了一下:…

SpringBoot 如何统一后端返回格式?老鸟们都是这样玩的!

大家好,我是磊哥。今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常。首先我们来看看为什么要返回统一的标准格式?为什么要对SpringBoot返回统一的标准格式在默认情况下&#…

zabbix企业应用之监控docker容器资源情况

关于docker的监控,无论开源的CAdvisor、Data Dog还是我自己写的监控(http://dl528888.blog.51cto.com/2382721/1635951),不是通过docker的stats api就是使用socket来进行。单独看一个主机的监控项还行,比如只查看容器t…

使用了synchronized,竟然还有线程安全问题!

线程安全问题一直是系统亘古不变的痛点。这不,最近在项目中发了一个错误使用线程同步的案例。表面上看已经使用了同步机制,一切岁月静好,但实际上线程同步却毫无作用。关于线程安全的问题,基本上就是在挖坑与填坑之间博弈&#xf…