之前发过一篇文章,简单了解 MySQL 中相关的锁,里面提到了,如果我们使用的 MySQL 存储引擎为 InnoDB ,并且其事务隔离级别是 RR 可重复读的话,是可以避免幻读的。

但是没想到,都 1202 年了都还有人杠,说 InnoDB 的 RR 隔离级别下会出现幻读,只能依靠 gap 和 next-key 这两个锁来防止幻读 ,最开始我还以为是他真的不知道这个点,就跟他聊,最后聊下来发现,发现是在钻牛角尖。

这个在下面讲到 可重复读 的隔离级别时会讲。

本来我觉得事务隔离级别这玩意儿太简单没啥可讲的,但是经过了上面这件事,我打算详细的把事务隔离给讲讲。接下来顺便就把 InnoDB 所有的事务隔离级别给搂一遍。

ACID

在聊事务隔离级别之前,我们需要知道 ACID 模型。


ACID 模型

分别代表:

  • Atomicity 原子性
  • Consistency 一致性
  • Isolation 隔离型
  • Durability 持久性

原子性,代表 InnoDB 事务中,所有的操作要么全部成功,要么全部失败,不会处于某个中间状态。说的更通俗一点,如果事务 A 失败,其所做的所有的更改应该全部回滚。

一致性,主要是保护数据的一致性,防止由于数据库的崩溃而导致的数据一致性问题。举个例子,我们更新 MySQL 的数据,更新的数据会先到 InnoDB 的 Buffer Pool 中,如果此时 MySQL 所在的机器突然意外重启了,如果 InnoDB 没有崩溃恢复机制,之前更新的数据就会丢失,数据的一致性问题就出现了。

很多其他的博客写的是事务开要始前后,数据的完整性没有被破坏。我表示看了根本看不懂,太抽象了。

隔离性,主要是指事务之间的隔离,再具体一点,就是我们本篇文章要讨论的事务隔离级别了。

持久性,主要是指我们新增或者删除了某些数据,一旦成功,这些操作应该需要被持久化到磁盘上去。

ACID 模型可以理解成数据库的设计范式,主要关注点在数据数据、及其本身的可靠性。而 MySQL 中的 InnoDB 就完全遵守 ACID 模型,并且在存储引擎层就支持数据一致性的校验和崩溃恢复的机制。

而 ACID 中的隔离型,就是我们这篇文章中讨论的重点。

事务隔离级别

有很多文章上来就直接介绍事务隔离级别的种类,这个种类啥意思,那个种类怎么用。但我认为应该先了解为什么需要事务隔离级别,以及事务隔离级别到底解决了什么问题,这才是关键。

我们知道 InnoDB 中同时会有多个事务对数据进行操作,举一些例子:

  • 假如事务A需要查询 id=1 的数据,但是事务A查询完毕之后,事务B对 id=1 的数据做了更新,那此时事务A再次执行查询,应该看到更新前的数据还是更新后的数据?
  • 或者还是上面那个例子,事务A读取了事务B的数据,但是如果事务B进行回滚了怎么办?事务A的数据不就变成了脏数据?
  • 又或者事务A读取了 1-3点 的日程安排,有4条,但是事务A读取完成后事务B又向 1-3 点这个时间段插入了一条新的安排,那么事务A如果再次读取,应该显示4条日程安排还是5条?

以上的这些问题,就需要事务隔离级别来回答了。其实以上的三种情况分别对应不可重复读脏读幻读。InnoDB 通过事务隔离级别分别的解决了上面的问题。所有的事务隔离级别如下:

  • READ UNCOMMITTED 读未提交
  • READ COMMITTED 读已提交
  • REPEATABLE READ 可重复读
  • SERIALIZABLE 串行化

InnoDB 默认的事务隔离级别为 REPEATABLE READ

读未提交

事务A读取了事务B还未提交的数据

如果事务B此时出错了进行了回滚,那么事务A读取到的数据就成为了脏数据,从而造成脏读

如果事务B又更新事务A读取的数据,那么事务A再次读取,读取到了事务B修改的结果,这造成了不可重复读

而如果事务B又新增了数据,事务A再次读取,会读取到事务B新增的数据,这造成了幻读

所以总结来说,在读未提交这个隔离级别下,会造成以下的问题:

  • 脏读
  • 不可重复读
  • 幻读

读已提交

事务A读取了事务B已经提交的数据

如果事务B更新了事务A读取到的数据,并且提交,那么当事务A再次进行读取,就会读取到其他事务的变更,就造成了不可重复读

同理,如果事务B新增了数据并且提交,事务A再次进行读取时拿到了事务B刚刚提交的数据,这就造成了幻读。

所以总结来说,在读已提交的隔离级别下,会造成:

  • 不可重复读
  • 幻读

可重复读

事务A不会读取到事务B更新的数据,也不会读到事务B新增的数据

在可重复读场景下,不会出现脏读、不会出现不可重复读,可能会出现幻读

无论事务B做了什么操作,事务A查询到的 id=1 的数据都是张三。

但是,在某些情况下,还是可能会出现 幻读可重复读 只是在某些情况下会产生幻读,但绝对不是 InnoDB 无法避免幻读。首先,InnoDB 在 RR 隔离级别下有很明确的解决幻读的方式,那就是——临键锁,一种组合了 gap 锁和记录锁的锁。

接下来举个例子来看在 RR 隔离级别下,什么情况会出现幻读,什么情况下不会出现幻读。首先是 可能会出现幻读

SELECT * FROM `student` WHERE `id` > 1

由于 InnoDB 有 MVCC 来进行多事务的并发,此时 SELECT 走的是快照读,不会加锁,那么临键锁就无法发挥其作用,如果有其他事务插入了一条数据,那么事务再次执行上面的语句是有可能会查出 id > 1 的数据。

但是如果显示的进行加锁,则可以避免这个问题。

SELECT * FROM `student` WHERE `id` > 1 FOR UPDATE

至于为什么临键锁可以避免幻读,之前的文章已经聊的很清楚,就不在此赘述了。

串行化

所以事务被强制的串行执行

这样从根本上就避免了并发的问题,但是这样会使得 MySQL 的性能下降。因为现在同一时间只能有一个事务在运行。

EOF

关于事务隔离级别就先介绍到这,之后有时间了就把 事务隔离级别 的底层原理给搂一遍。

本篇文章已放到我的 Github github.com/sh-blog 中,欢迎 Star。微信搜索关注【SH的全栈笔记】,回复【队列】获取MQ学习资料,包含基础概念解析和RocketMQ详细的源码解析,持续更新中。

如果你觉得这篇文章对你有帮助,还麻烦点个赞关个注分个享留个言

啥是 MySQL 事务隔离级别?的更多相关文章

  1. [51CTO]新说MySQL事务隔离级别!

    新说MySQL事务隔离级别! 事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!本文所讲大部分内容,皆有官网作为佐证,因此对本文内 ...

  2. 查询mysql事务隔离级别

    查询mysql事务隔离级别 查询mysql事务隔离级别 分类: DB2011-11-26 13:12 2517人阅读 评论(0) 收藏 举报 mysqlsessionjava   1.查看当前会话隔离 ...

  3. MySQL事务隔离级别测试实例

    https://www.cnblogs.com/huanongying/p/7021555.html MySQL事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommit ...

  4. Mysql事务-隔离级别

    MYSQL事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被 ...

  5. MySQL事务隔离级别 解决并发问题

    MySQL事务隔离级别 1. 脏读: 骗钱的手段, 两个窗口或线程分别调用数据库转账表,转账后未提交,对方查看到账后,rollback,实际钱没转. 演示方法: mysql默认的事务隔离级别为repe ...

  6. mysql事务隔离级别、脏读、幻读

    Mysql事务隔离级别本身很重要,再加上可能是因为各大公司面试必问的缘故,在博客中出现的概率非常高,但不幸的是,中国的技术博客要么是转载,要么是照抄,质量参差不齐,好多结论都是错的,对于心怀好奇之心想 ...

  7. mysql事务隔离级别与设置

    mysql数据库,当且仅当引擎是InnoDB,才支持事务: 1.隔离级别 事务的隔离级别分为:未提交读(read uncommitted).已提交读(read committed).可重复读(repe ...

  8. MySQL事务隔离级别(二)

    搞清楚MySQL事务隔离级别 首先创建一个表 account.创建表的过程略过(由于 InnoDB 存储引擎支持事务,所以将表的存储引擎设置为 InnoDB).表的结构如下: 为了说明问题,我们打开两 ...

  9. MySQL事务隔离级别(一)

    本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...

  10. 面试突击61:说一下MySQL事务隔离级别?

    MySQL 事务隔离级别是为了解决并发事务互相干扰的问题的,MySQL 事务隔离级别总共有以下 4 种: READ UNCOMMITTED:读未提交. READ COMMITTED:读已提交. REP ...

随机推荐

  1. 实验6、Flask API使用示例和拓展

    实验介绍 1. 实验内容 Flask 提供了多种API拓展,本节我们主要学习基于RESTful的Flask应用程序设计 2. 实验要点 学习和掌握多种RESTful的设计模式 3.实验环境 Cento ...

  2. 【接口测试】-1.常用的接口测试工具(Postman、soupUI、Jemeter)

      1)  Postman 1.get/post请求--  postman获取用户信息1 get方式:可以直接在url中写入参数 Post方式:请求体可以写到URL或Body的form-data中写参 ...

  3. noip模拟8[星际旅行·砍树·超级树·求和]

    也不能算考得好,虽然这次A了一道题,但主要是那道题太简单了,没啥成就感,而且有好多人都A掉了 除了那一道,其他的加起来一共拿了25pts,这我能咋办,无奈的去改题 整场考试的状态并不是很好啊,不知道是 ...

  4. 尼恩 Java高并发三部曲 [官方]

    高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三部曲 > 面试必备 + 大厂必备 + 涨薪 ...

  5. Linux面试题(史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  6. 别再说Java对象都是在堆内存上分配空间的了!

    Java作为一种面向对象的,跨平台语言,其对象.内存等一直是比较难的知识点,所以,即使是一个Java的初学者,也一定或多或少的对JVM有一些了解.可以说,关于JVM的相关知识,基本是每个Java开发者 ...

  7. Mysql优化(出自官方文档) - 第二篇

    Mysql优化(出自官方文档) - 第二篇 目录 Mysql优化(出自官方文档) - 第二篇 1 关于Nested Loop Join的相关知识 1.1 相关概念和算法 1.2 一些优化 1 关于Ne ...

  8. 手摸手,带你用Beego撸商城系列二(登录篇)

    完整项目地址: go-shop-b2c 系列文章: 手摸手,带你用 Beego撸商城 系列一(基础篇) 手摸手,带你用 Beego撸商城 系列二(登录篇) 手摸手,带你用 Beego撸商城 系列三(系 ...

  9. 5、rsync全网备份

    定时备份rsync(增量备份,无差异备份,daemon进程)+crontab,主要备份一些任务脚本和配置文件,如果此时有用户增加数据, 如果是增量备份的话不会备份下来,因为在备份的那一刻,数据已经被锁 ...

  10. [Django REST framework - RBAC-基于角色的访问控制、base64编码 、xadmin的使用]

    [Django REST framework - RBAC-基于角色的访问控制.base64编码 .xadmin的使用] RBAC-基于角色的访问控制 RBAC 是基于角色的访问控制(Role-Bas ...