△Hollis, 一个对Coding有着独特追求的人△

这是Hollis的第 356 篇原创分享

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

本文小结

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

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

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


往期推荐

密码打马赛克已经不安全了!这款开源的去“马赛克“工具一秒还原

身家破亿!86版西游记“红孩儿”拒绝出道成学霸,已是中科院博士,名下52家公司

带爸妈去上海东方明珠旋转餐厅体验了一把

直面Java第360期:如何使用乐观锁提升高并发的吞吐率并且不会超卖

深入并发第015期:多线程代码如何Debug?

如果你喜欢本文,

请长按二维码,关注 Hollis.

转发至朋友圈,是对我最大的支持。

点个 在看 

喜欢是一种感觉

在看是一种支持

↘↘↘

再有人问你MySql 的隔离级别是什么,就把这篇文章发给他!相关推荐

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

    作者 l zyz1992 来源 l Hollis(ID:hollischuang) 首先要明白什么是事务? 事务是程序中一系列严密的操作,所有的操作必须完成,否则在所有的操作中所做的所有的更改都会被撤 ...

  2. 再有人问你MySQL索引原理,就把这篇文章甩给他!

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 335 篇原创分享 作者 l zyz1992 来源 l Hollis(ID:hollischuang) 索引,可能让好很多 ...

  3. 再有人问你MySQL是如何查询数据的,请把这篇文章甩给他!

    上一篇我们说到了关于MySQL的索引的原理,主要说的是 MySQL 对于索引的字段是怎么去维护的,我们再来简单的回顾下: MySQL 对于主键索引的维护是最简单的,就是根据主键去维护一个 B+ 树,因 ...

  4. 再有人问你synchronized是什么,就把这篇文章发给他。

    在<深入理解Java虚拟机>中,有这样一段话: synchronized关键字在需要原子性.可见性和有序性这三种特性的时候都可以作为其中一种解决方案,看起来是"万能"的 ...

  5. 再有人问你volatile是什么,就把这篇文章发给他

    转载自  再有人问你volatile是什么,就把这篇文章发给他 在再有人问你Java内存模型是什么,就把这篇文章发给他中我们曾经介绍过,Java语言为了解决并发编程中存在的原子性.可见性和有序性问题, ...

  6. 再有人问你volatile是什么,把这篇文章也发给他(深入分析)

    转载自  再有人问你volatile是什么,把这篇文章也发给他 在上一篇文章中,我们围绕volatile关键字做了很多阐述,主要介绍了volatile的用法.原理以及特性.在上一篇文章中,我提到过:v ...

  7. 再有人问你为什么MySQL用B+树做索引,就把这篇文章发给她

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 234 篇原创分享 作者 l 安静的boy 来源 l Hollis(ID:hollischuang) 索引这个词,相信大多 ...

  8. 再有人问你什么是分库分表,直接把这篇文章发给他

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 393 篇原创分享 作者 l Hollis 来源 l Hollis(ID:hollischuang) Hollis的新书限 ...

  9. redisson的锁的类型_再有人问你分布式锁是什么,就把这个丢给他!

    [小宅按]现在面试都会聊聊分布式系统,通常面试官都会从服务框架(Spring Cloud.Dubbo),一路聊到分布式事务.分布式锁.ZooKeeper 等知识.今天就来聊聊分布式锁这块的知识,先具体 ...

最新文章

  1. linux装nginx
  2. Codeforces 785 D.Anton and School - 2(组合数处理)
  3. mysql zrm 配置_利用MySQL-zrm来备份和恢复MySQL数据库方法详解
  4. 设置android电话震动,Android手机震动的设置步骤
  5. 周赛 Hd2270+总结改进
  6. MD5计算,一个扩展类,哪里都能用
  7. mysql无法添加或更新子行_MySQL错误1452-无法添加或更新子行:外键约束失败?
  8. 仙岛求药(信息学奥赛一本通-T1251)
  9. 函数 的 重载 和 函数 模版
  10. DID会固定年份吗_倍分法DID详解 (二):多时点 DID (渐进DID)
  11. 代码管理学:改名这样的事情,还真不是一般人能做的
  12. java图书管理系统开发环境_应用Java开发图书管理系统
  13. 我的世界java 4k_我的世界:原版VS“4K光影”牺牲2块显卡,让你看看差距有多大!...
  14. FRM考试时间明细,FRM考试全方面日程表
  15. 装两个独立的双系统,在笔记本电脑上
  16. Nano配置永久静态IP
  17. 静态页面:html5个人博客模板《绅士》
  18. LiveNVR监控流媒体Onvif/RTSP功能支持海康摄像头通过海康SDK的方式接入直播观看录像回看预置位操作
  19. medium_socnet靶场
  20. 16 | 网络优化(中):复杂多变的移动网络该如何优化?

热门文章

  1. 全国高等学校计算机等级用处,全国计算机等级考试一级有什么用
  2. python tesseract ocr_使用Python和Tesseract OCR解决Captch
  3. windows7官方原版_从零开始学装系统——微软官方原版windows7详细安装流程
  4. android获取文件夹里最新的文件夹,Android 获取已存在的文件所在目录下的所有文件为null。...
  5. 回顾 - 判断质数精简算法
  6. 计算机网络之数据链路层:3、差错控制(奇偶校验、CRC冗余校验、海明校验)
  7. (数据库系统概论|王珊)第六章关系数据理论-第一节:为什么要研究关系数据理论
  8. Linux系统编程13:进程入门之Linux中的环境变量的概念及其相关命令(export;env等)main函数的参数
  9. windows 获取系统CPU和进程CPU 内存等信息
  10. RSA算法原理简介,非对称加密,公开密钥算法(易懂篇)