mysql的默认事务隔离级别(啥是 MySQL 事务隔离级别?)
mysql的默认事务隔离级别
啥是 MySQL 事务隔离级别?
之前发过一篇文章,简单了解 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
关于事务隔离级别就先介绍到这,之后有时间了就把 事务隔离级别 的底层原理给搂一遍。
原文地址:https://mp.weixin.qq.com/s/VAfR8MVw18Yt-sfe4t22NQ
- mysql如何删除外键约束数据(MySQL中外键的创建、约束以及删除)
- mysql索引的机制(Mysql索引选择以及优化详解)
- mysql数据库使用规则(mysql数据库基本语法及操作大全)
- mysql提高分页效率(MySQL优化教程之超大分页查询)
- mysql主键什么情况用uuid(Mysql主键UUID和自增主键的区别及优劣分析)
- mysql数据库简单操作(一篇文章教会你进行MySQL数据库和数据表的基本操作)
- mysql各种备份方式(MySQL 逻辑备份与恢复测试的相关总结)
- mysql8.0.15官方最新版本安装教程(MySQL8.0.24版本Release Note的一些改进点)
- SQL SERVER与MySQL数据类型的对应关系
- mysql复合索引会包含哪些索引(MySQL查询冗余索引和未使用过的索引操作)
- 如何排查mysql存储过程的问题(Mysql修改存储过程相关权限问题)
- mysql 慢查询日志
- MySQL配置文件my.cnf的介绍
- mysqlsource命令作用(MySQL source命令的使用简介)
- docker搭建mysql服务(Docker部署Mysql集群的实现)
- mysql中自增字段类型(MySQL数字类型自增的坑)
- 冰岛旅游攻略(冰岛旅游攻略及花费八日游)
- 寒假旅游攻略(成都寒假旅游攻略)
- 菲律宾旅游攻略(菲律宾旅游攻略地图)
- 清华大学难考吗(清华大学考研录取分数线)
- 观花盆栽佛肚竹盆景制作及养护(观花盆栽佛肚竹盆景制作及养护)
- 春天养佛肚竹,做好这几件事,叶绿根壮寓意好 越养越旺家(春天养佛肚竹做好这几件事)
热门推荐
- :link,:visited,:focus,:hover,:active的用法
- php协议使用教程学习(php中的钩子理解及应用实例分析)
- js的逻辑关系和思路(js Proxy的原理详解)
- canvas绘图白屏或者元素有缺失(高清屏中使用Canvas绘图出现模糊的问题及解决方法)
- dedecms的dedesql.class.php on line 489错误的解决方法(dedecms的dedesql.class.php on line 489错误的解决方法)
- 服务器的维护与管理(浅谈网站服务器的维护管理)
- linux解压zip文件的命令(Linux gzip 命令的使用)
- dedecms制作的网站如何发布(DedeCms后台添加编辑文章空白的解决方法)
- antdesign接收数据状态(Ant Design Blazor 组件库的路由复用多标签页功能)
- python入门知识点总结(深入解析Python小白学习操作列表)