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

时间:2023-01-25 09:28:48

新说MySQL事务隔离级别!

事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!本文所讲大部分内容,皆有官网作为佐证,因此对本文内容你可以看完后,你完全可以当概念记在脑海里,除非官网的开发手册是错的,否则应当无误!

http://database.51cto.com/art/201812/589087.htm

引言

大家在面试中一定碰到过

说说事务的隔离级别吧?

老实说,事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!因为他们对可重复读(Repeatable Read)和串行化(serializable)的解析实在是看的我一头雾水!

再加上很多书都说可重复读解决了幻读问题,比如《mysql技术内幕--innodb存储引擎》等,不一一列举了,因此网上关于事务隔离级别的文章大多是有问题的,所以再开一文说明!

本文所讲大部分内容,皆有官网作为佐证,因此对本文内容你可以看完后,你完全可以当概念记在脑海里,除非官网的开发手册是错的,否则应当无误!

另外,本文会重点说一下

可重复读(Repeatable Read)是否真的解决幻读的问题!

正文

开始我先提一下,根据事务的隔离级别不同,会有三种情况发生。即脏读、不可重复读、幻读。这里我先不提这三种情况的定义,后面在讲隔离级别的时候会补上。

这里,大家记住一点,根据脏读、不可重复读、幻读定义来看(自己总结,官网没有),有如下包含关系:

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

那么,这张图怎么理解呢?

即,如果发生了脏读,那么不可重复读和幻读是一定发生的。因为拿脏读的现象,用不可重复读,幻读的定义也能解释的通。但是反过来,拿不可重复读的现象,用脏读的定义就不一定解释的通了!

假设有表tx_tb如下,pId为主键

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

读未提交

即READ_UNCOMMITTED,其实这个从隔离名字就可以看出来,一个事务可以读到另一个事务未提交的数据!为了便于说明,我简单的画图说明!

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

如图所示,一个事务检索的数据被另一个未提交的事务给修改了。

官网对脏读定义的地址为https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_dirty_read

其内容为

dirty read

An operation that retrieves unreliable data, data that was updated by another transaction but not yet committed.

翻译过来就是

检索操作出来的数据是不可靠的,是可以被另一个未提交的事务修改的!

你会发现,我们的演示结果和官网对脏读的定义一致。根据我们最开始的推理,如果存在脏读,那么不可重复读和幻读一定是存在的。

读已提交

即READ_COMMITTED,这个也能看的出来,一个事务能读到另一个事务已提交的数据!为了便于说明,我简单的画图说明!

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

如图所示,一个事务检索的数据只能被另一个已提交的事务修改。

官网对不可重复读定义的地址为

https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_non_repeatable_read

其内容为

non-repeatable read

The situation when a query retrieves data, and a later query within the same transaction retrieves what should be the same data, but the queries return different results (changed by another transaction committing in the meantime).

翻译过来就是

一个查询语句检索数据,随后又有一个查询语句在同一个事务中检索数据,两个数据应该是一样的,但是实际情况返回了不同的结果。(同时被另一个正在提交的事务修改了)!

ps:作者注,这里的不同结果,指的是在行不变的情况下(专业点说,主键索引没变),但是主键索引指向的磁盘上的数据内容变了。如果主键索引变了,比如新增一条数据或者删除一条数据,就不是不可重复读。

显然,我们这个现象符合不可重复读的定义。下面,大家做一个思考:

  • 这个不可重复读的定义,放到脏读的现象里是不是也可以说的通。显然脏读的现象,也就是读未提交的那个例子,是不是也符合在同一个事务中返回了不同结果!
  • 但是反过来就不一定通了,一个事务A中查询两次的结果在被另一个事务B改变的情况下,如果事务B未提交就改变了事务A的结果,就属于脏读,也属于不可重复读。如果该事务B提交了才改变事务A的结果,就不属于脏读,但属于不可重复读。

可重复读

即REPEATABLE_READ。这里,我改变一下顺序,先上幻读的定义

官网对幻读定义的地址为

https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_phantom

phantom

A row that appears in the result set of a query, but not in the result set of an earlier query. For example, if a query is run twice within a transaction, and in the meantime, another transaction commits after inserting a new row or updating a row so that it matches the WHERE clause of the query.

翻译过来就是

在一次查询的结果集里出现了某一行数据,但是该数据并未出现在更早的查询结果集里。例如,在一次事务里进行了两次查询,同时另一个事务插入某一行或更新某一行数据后(该数据符合查询语句里where后的条件),并提交了!

好了,接下来上图,大家自己评定该现象是否符合幻读的定义

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

显然,该现象是符合幻读的定义的。同一事务的两次相同查询出现不同行。下面,大家做一个思考:

  • 这个幻读的定义,放到上面不可重复读的现象里是不是也可以说的通。大家自行思考!
  • 反过来就不一定通了。事务第二次查询出了一个数据,但是该数据并未出现在第一次查询的结果集里。如果该数据是修改数据,那么该现象既属于不可重复读,也属于幻读。如果该数据是新增或删除的数据,那该现象就不属于不可重复读,但属于幻读。

接下来说一下,为什么很多文章都产生误传,说是可重复读可以解决幻读问题!原因出自官网的一句话

地址:https://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html#innodb-record-locks

原文内容如下

By default, InnoDB operates in REPEATABLE READ transaction isolation level. In this case, InnoDB uses next-key locks for searches and index scans, which prevents phantom rows (see Section 14.7.4, “Phantom Rows”).

按照原本这句话的意思,应该是

InnoDB默认用了REPEATABLE READ。在这种情况下,使用next-key locks解决幻读问题!

结果估计,某个国内翻译人员翻着翻着变成了

InnoDB默认用了REPEATABLE READ。在这种情况下,可以解决幻读问题!

然后大家继续你抄我,我抄你,结果你懂的!

显然,漏了"使用了next-key locks!"这个条件后,意思完全改变,我们在该隔离级别下执行语句

  1. select * from tx_tb where pId >= 1;

是快照读,是不加任何锁的,根本不能解决幻读问题,除非你用

  1. select * from tx_tb where pId >= 1 lock in share mode;

这样,你就用上了next-key locks,才能解决幻读问题!

串行读

即SERIALIZABLE_READ。在该隔离级别下,所有的select语句后都自动加上lock in share mode。因此,在该隔离级别下,无论你如何进行查询,都会使用next-key locks。所有的select操作均为当前读!

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

OK,注意看上表红色部分!就是因为在该隔离级别下使用了next-key locks,innodb将pId=1这条索引记录,和(1,++∞)这个间隙锁住了。其他事务要在这个间隙上插数据,就会阻塞,从而防止幻读发生!

有的人会说,你这第二次查询的结果,也变了啊,明显和第一次查询结果不一样啊?对此,我只能说,请看清楚啊。这是被自己的事务改的,不是被其他事物修改的。这不算是幻读,也不是不可重复读。

总结

上面罗里吧嗦一大堆,最后来一个表格做总结吧,你面试答这个表就行。上面的一切是为了这张表做准备!

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

[51CTO]新说MySQL事务隔离级别!的更多相关文章

  1. 【原创】新说Mysql事务隔离级别

    引言 大家在面试中一定碰到过 说说事务的隔离级别吧? 老实说,事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!因为他们对可重复读 ...

  2. 【转】新说Mysql事务隔离级别

    作者:孤独烟 转自:https://www.cnblogs.com/rjzheng/p/9955395.html 引言 大家在面试中一定碰到过 说说事务的隔离级别吧? 老实说,事务隔离级别这个问题,无 ...

  3. 查询mysql事务隔离级别

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

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

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

  5. Mysql事务-隔离级别

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

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

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

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

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

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

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

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

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

随机推荐

  1. 分布式大数据高并发的web开发框架

    一.引言 通常我们认为静态网页html的网站速度是最快的,但是自从有了动态网页之后,很多交互数据都从数据库查询而来,数据也是经常变化的,除了一些新闻资讯类的网站,使用html静态化来提高访问速度是不太 ...

  2. Using Apache Maven

    Apache Maven是一个软件项目管理的综合工具(management and comprehension tool).可以将WAR文件部署到App Engine中.为了加快部署的速度,App E ...

  3. 见过的最好AWK手册

    原文: http://linuxfire.com.cn/~lily/awk.html 简体中文版由bones7456 (http://li2z.cn)整理. 原文:应该是 http://phi.sin ...

  4. WinForm 控件的布局(Dock属性)的注意点

    对于Dock属性,添加控件的顺序会影响它们停驻的方式.例如,如果你对窗体添加控件A,指示其停驻填充(Fill), 然后你对窗体添加控件B并指示其停驻顶部(Top),控件B将覆盖控件A的上部.原因就是控 ...

  5. OBJ文件格式分析工具: objdump, nm,ar

    首先简要阐述关于gcc.glibc和 binutils模块之间的关系 一.关于gcc.glibc和binutils模块之间的关系 1.gcc(gnu collect compiler)是一组编译工具的 ...

  6. [转帖]Oracle 补丁体系(PSR/PSU/CPU) 及 opatch 工具 介绍

    Oracle 补丁体系(PSR/PSU/CPU) 及 opatch 工具 介绍 原文:http://blog.csdn.net/tianlesoftware/article/details/58095 ...

  7. linux系统中文件的权限

    查看文件权限的语句: 在终端输入:ls -l xxx.xxx (xxx.xxx是文件名) 那么就会出现相类似的信息,主要都是这些:-rw-rw-r-- 一共有10位数 其中: 最前面那个 - 代表的是 ...

  8. Linux文件大小排序

    ls 文件详情 ls   -S /            ###从大到小排序ls   -Sr /          ###从小到大排就加个-r     -r 翻转ls   -aSr /         ...

  9. TCP Three-way Handshake

    TCP Connection Management Out-of-Order and Duplication(复制) Problem Old segment from previous connect ...

  10. 设计模式之享元(flyweight)模式

    现在在大力推行节约型社会,“浪费可耻,节俭光荣”.在软件系统中,有时候也会存在资源浪费的情况,例如,在计算机内存中存储了多个完全相同或者非常相似的对象,如果这些对象的数量太多将导致系统运行代价过高.那 ...