MySQL中的幻读,你真的理解吗?
昨天接到阿里的电话面试,对方问了一个在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和「幻读」了
The so-called phantom problem occurs within a transaction when the same query produces different set ...
- 【Java面试】这应该是面试官最想听到的回答,Mysql如何解决幻读问题?
"Mysql如何解决幻读问题" 一个工作了4年小伙伴,去一个美团面试,遇到了这样一个问题. 大家好,我是Mic,一个工作了14年的Java程序员 关于这个问题,面试官想考察什么?我 ...
- 3个问题:MySQL 中 character set 与 collation 的理解;utf8_general_ci 与 utf8_unicode_ci 区别;uft8mb4 默认collation:utf8mb4_0900_ai_ci 的含义
MySQL 中 character set 与 collation 的理解 出处:https://www.cnblogs.com/EasonJim/p/8128196.html 推荐: 编码使用 uf ...
- MYSQL事件隔离级别以及复读,幻读,脏读的理解
一.mysql事件隔离级别 1未提交读(READUNCOMMITTED) 另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)( 隔离级别最低,并发性能高 ) 2 ...
- MYSQL如何解决幻读
第一部分 首先要了解下mysql数据库的事务特征之一隔离级别: READ UNCOMMITTED(未提交读): 在READUNCOMMITTED级别,事务中的修改,即使没有提交,对其他事务也都是可见的 ...
- 对于C#中的一些点滴你真的理解了吗?
废话不多说看题目,看看我们自己真的理解了吗? 1.如下代码输出的结果是什么? public class A{ public virtual void Func(int number=10) { Co ...
- MYSQL中TIMESTAMP类型的默认值理解
MYSQL中TIMESTAMP类型可以设定默认值,就像其他类型一样. 1.自动UPDATE 和INSERT 到当前的时间:表:----------- Table Create Table ...
- mysql 中 character set 与 collation 的理解
character set 和 collation 的是什么? character set, 即字符集. 我们常看到的 utf-8, GB2312, GB18030 都是相互独立的 character ...
- MySQL中character set与collation的理解(转)
character set和collation的是什么? character set即字符集 我们常看到的UTF-8.GB2312.GB18030都是相互独立的character set.即对Unic ...
随机推荐
- mysql 用户操作和授权
1.查看mysql的版本 mysql -V 2.用户操作 # 创建用户 create user 'username'@'ip地址' identified by '密码'; # 用户重命名 rename ...
- IDEA中springboot的热部署
在pom.xml文件中添加依赖 <!--添加热部署--> <dependency> <groupId>org.springframework.boot</gr ...
- python算法学习总结
数据结构一维: 基础:数组array(string),链表Linked List 高级:栈stack,队列queue,双端队列deque,集合set,映射map(hash or map), etc二维 ...
- 机器学习-TensorFlow应用之 binned features, Cross features和optimizer
概述 这一节主要介绍一下TensorFlow在应用的过程中的几个小的知识点,第一个是关于features的处理的,例如Bucketized (Binned) Features 和 Feature sc ...
- 史上最简单的的HashTable源码分析
HashTable源码分析 1.前言 Hashtable 一个元老级的集合类,早在 JDK 1.0 就诞生了 1.1.摘要 在集合系列的第一章,咱们了解到,Map 的实现类有 HashMap.Link ...
- JS-01-js的三种引入方式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 《ASP.NET Core 高性能系列》ASP.NET Core的启动过程(1)
一.一切从头开始 简述:知道事情的真相就应该从头 开始,下面我们代码先行 public class Program { public static void Main(string[] args) { ...
- Tomcat项目启动常见错误以及原因,持续更新.........
一 Context initialization failed 错误截图: 原因: jdk版本与项目不对应,可重新设置项目jdk和ide编译的jdk即可
- 异常处理 | manual close is not allowed over a Spring managed SqlSession
背景: 今天启动一个老项目,控制台打印出以下异常,大概是说在Spring托管的SqlSession上不允许手动关闭: java.lang.UnsupportedOperationException: ...
- artTemplate--模板使用自定义函数(1)
案例 因为公司业务需要频繁调用接口,后端返回的都是json树对象,需要有些特殊的方法做大量判断和数据处理,显然目前简单语法已经不能满足业务需要了,需要自己定制一些 方法来处理业务逻辑. 例如后台返回的 ...