MySQL中的幻读,你真的理解吗?

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介:

昨天接到阿里的电话面试,对方问了一个在MySQL当中,什么是幻读。当时一脸懵逼,凭着印象和对方胡扯了几句。面试结束后,赶紧去查资料,才发现之前对幻读的理解完全错误。下面,我们就聊聊幻读。

要说幻读,就要从MySQL的隔离级别说起。MySQL的4钟隔离级别分别是:

Read Uncommitted(读取未提交内容)

在该隔离级别,所有事务都可以看到其他未提交事务的执行结果。本隔离级别很少用于实际应用,因为它的性能也不比其他级别好多少。读取未提交的数据,也被称之为脏读(Dirty Read)。

脏读的具体示例如下:

时间点 事务A 事务B
1 开启事务
2 开启事务
3 查询数据为100条
4 insert一条数据
5 再查询,结果为101条

在时间点5,事务A再次查询数据时,事务B并没有提交事务,但是,新的数据也被事务A查出来了。这就是脏读。

Read Committed(读取提交内容)

这是大多数数据库系统的默认隔离级别(但不是MySQL默认的)。它满足了隔离的简单定义:一个事务只能看见已经提交事务所做的改变。这种隔离级别 也支持所谓的不可重复读(Nonrepeatable Read),因为同一事务的其他实例在该实例处理其间可能会有新的commit,所以同一select可能返回不同结果。

时间点 事务A 事务B
1 开启事务
2 开启事务
3 查询数据为100条
4 insert一条数据
5 查询数据为100条
6 提交事务
7 查询数据为101条

我们可以看到,事务B在提交事务之前,事务A的两次查询结果是一致的。事务B提交事务以后,事务A再次查询,查询到了新增的这条数据。在事务A中,多次查询的结果不一致,这就是我们说的“不可重复读”。

Repeatable Read(可重读)

这是MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。不过理论上,这会导致另一个棘手的问题:幻读 (Phantom Read)。简单的说,幻读指当用户读取某一范围的数据行时,另一个事务又在该范围内插入了新行,当用户再读取该范围的数据行时,会发现有新的“幻影” 行。

上面这一段是MySQL官方给出的解释,听着云里雾里。“可重读”这种隔离级别解决了上面例子中的问题,保证了同一事务内,多次查询的结果是一致的。也就是说,事务B插入数据提交事务后,事务A的查询结果也是100条,因为事务A在开启事务时,事务B插入的数据还没有提交。

但是,这又引出了另外一个情况,“幻读”。这个幻读我之前理解是有问题的,在面试时,被对方一顿质疑。现在我们就看看幻读的正确理解:

时间点 事务A 事务B
1 开启事务
2 开启事务
3 查询数据“张三”,不存在
4 插入数据“张三”
5 提交事务
6 查询数据“张三”,不存在
7 插入数据“张三”,不成功

事务A查询“张三”,查询不到,插入又不成功,“张三”这条数据就像幻觉一样出现。这就是所谓的“幻读”。网上对“幻读”还是其他的解释,都是错误的。比如像“幻读”和“不可重复读”是一样,只不过“幻读”是针对数据的个数。这些理解都是错误的。

Serializable(可串行化)

这是最高的隔离级别,它通过强制事务排序,使之不可能相互冲突,从而解决幻读问题。简言之,它是在每个读的数据行上加上共享锁。在这个级别,可能导致大量的超时现象和锁竞争。这种隔离级别很少使用,不给大家做过多的介绍了。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
SQL 关系型数据库 MySQL
【Mysql】数据库事务,脏读、幻读、不可重复读
【Mysql】数据库事务,脏读、幻读、不可重复读
【Mysql】数据库事务,脏读、幻读、不可重复读
|
关系型数据库 MySQL 数据库
MySQL事务的隔离级别以及脏读、幻读和不可重复读
MySQL事务的隔离级别以及脏读、幻读和不可重复读
|
SQL 关系型数据库 MySQL
你知道MySQL是如何解决幻读的吗?
你知道MySQL是如何解决幻读的吗?
379 0
你知道MySQL是如何解决幻读的吗?
|
SQL Oracle 关系型数据库
Mysql模拟事物的隔离级别【脏读、不可重复读、幻读】
Mysql模拟事物的隔离级别【脏读、不可重复读、幻读】
195 0
Mysql模拟事物的隔离级别【脏读、不可重复读、幻读】
|
SQL 关系型数据库 MySQL
【MySQL】可重复读隔离级别是否解决了幻读?
面试官:可重复读隔离级别是否解决了幻读了吗?不清楚是吧,没关系,那我们今天面试就先到这。
237 0
【MySQL】可重复读隔离级别是否解决了幻读?
|
关系型数据库 MySQL 数据库
Mysql-详解脏读、不可重复读、幻读
Mysql-详解脏读、不可重复读、幻读
Mysql-详解脏读、不可重复读、幻读
|
存储 SQL 关系型数据库
MySQL的可重复读级别能解决幻读吗?MYSQL指的幻读到底是什么?
首先,要搞懂这个问题,我们需要先了解Mysql事务的四种隔离级别以及平常我们说的幻读的概念。由于这俩概念比较简单,强哥在这几就简单的带大家复习一下。
MySQL的可重复读级别能解决幻读吗?MYSQL指的幻读到底是什么?
|
关系型数据库 MySQL 数据库
MySQL事务的隔离级别以及脏读、幻读和不可重复读
ACID,是指数据库管理系统(DBMS)在写入或更新的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity)、一致性(consistency)、隔离性(isolation)、持久性(durability)
150 0
MySQL事务的隔离级别以及脏读、幻读和不可重复读
|
缓存 关系型数据库 MySQL
MySQL中脏读、不可重复读、幻读
简单聊聊mysql的脏读、不可重复读、幻读
179 0
|
SQL 关系型数据库 MySQL
MySQL到底在RR层面解决幻读了吗?
hi,好久不见。 最近工作上有一些变动,文章很少更新。不过平时还是有收集一些文章idea,后面有空会慢慢写~
1051 0