Mysql事务隔离级别本身很重要,再加上可能是因为各大公司面试必问的缘故,在博客中出现的概率非常高,但不幸的是,中国的技术博客要么是转载,要么是照抄,质量参差不齐,好多结论都是错的,对于心怀好奇之心想弄明白问题的同学来说,这些博客是很危险的。我当时也是看了各种版本的博客之后,翻官网,做实验,最终搞明白了一些事情,写在这里,希望对后来人有所帮助。

事务隔离级别
先说什么叫做“事务隔离”,事务隔离是指多个事务同时在进行中(如果只有一个事务,那就无所谓隔离不隔离了)时,各个事务被隔离开来,相互之间的影响和事物的隔离级别有关,按照“读未提交”–>“读已提交”–>“可重复读”–>“串行化”的顺序,越往后面隔离级别越高,事务之间的影响越小。
下面的内容都以这个数据表为例进行说明:

id money
1 10
2 20
4 40
读未提交和脏读
两个同时进行的事务A、B,A会读到B还未提交的的数据,这种事务隔离级别会存在脏读的问题,举个例子:
B修改id=2的money为200,但是尚未提交,然后A读取id为2的money,这是读到的值是200,然后B因为某种原因(比如系统异常)导致事务回滚了,此时2最终的money仍然是20。说明A读到了脏数据。
    A                        B
                             begin
                    update table set money = 200 where id = 2
select money from table where id = 2
                           rollback

读已提交和不可重复读
为了解决脏读的问题,可以将事务隔离级别调整到“读已提交”,这种隔离级别下,事务A只能读到事务B提交后的数据,但是这种隔离级别虽然解决了脏读的问题,但是无法解决可重复读的问题,即在事务A中,两次执行相同的读取语句,读到的内容却是不一样的。举例如下
      A                        B
      begin                       begin
                    update table set money = 200 where id = 2
select money from table where id = 2
                           commit
select money from table where id = 2
     commit

事务A中第一次select时,读到的值是20,第二次再执行select时,读取到的值是200。这就是不可重复读。

可重复读
为了解决不可重复读的问题,可以将事务隔离级别调整到“可重复读”,这种隔离级别下,可以保证在同一个事务中只会读取到当前事务对数据的修改,其他事务修改的数据不会影响到当前事务的任何一次读取。还是上面的例子,事务A两次select读取到的结果都是20,即可重复读.

幻读
可重复读虽然解决了不可重复读的问题,但是仍然存在幻读的问题。

错误的说法
对于幻读的解释,大多数博客中都是有问题的,甚至《高性能mysql》中,也没有详细解释幻读的问题
我们先来看看网上出现最多的幻读的解释,务必注意,这种解释是错误的:
       A                        B
       begin                      begin
select money from table where id > 2
                           inser into table values(3,30)
                              commit
select money from table where id > 2
       commit

网上多数观点认为,当A进行范围查询时,B在其中插入一条数据,A再次执行该范围查询是,就会比第一次查询时多出来B刚才插入的那条数据,像幻影一样,所以出现了幻读。
为什么这种说法是不对的呢?
从实践上看,直接去msql中试试就会发现,其实A连个执行的查询结果仍然是一样的,并不会出现幻读的现象。
从原理上看,可重复读是靠MVCC(多版本并发控制)保证的,该模式下,保证事务只能读取到当前事务开启之前已经提交的事务进行的修改以及当前事务本身对数据的修改。按照这个定义,上述实验中的B事务并不会影响到A的读取。

真正的幻读
那么什么事真正的幻读呢?来看下面的例子
A                        B
       begin                      begin
select money from table where id > 2
                           inser into table values(3,30)
                              commit
update table set money = 0 where id > 2
select money from table where id > 2
       commit

在B事务提交之后,A事务第二次select之前,先进行一次update操作,然后A再次执行select时,id=3的行就会出现,而且money的值是0.出现了幻读。

出现幻读的原因
MVCC只对读有效,对写操作无效,由于update是写操作,所以为更新B已经插入的id=3的行,将money更新成0,此时id=3的行被A事务(当前事务)修改了,所以A事务中第二次select时,是可以看到被当前事务修改(update)的数据的,所以id=3的行会出现在select的结果中,这就是幻读出现的原因。

串行
串行将所有的事务一个接一个的进行,不存在多个事务同事进行的情况,所以串行的事务隔离级别不会出现上面提到的脏读、不可重复读、幻读等任何一种问题。代价是,严重影响了数据库的性能。

事务隔离级别的选择
事务隔离级别需要根据具体的业务场景来选择,并没有哪一个级别是万能的。
有些场景下,甚至根本不需要事务,这时候,也许MyIsam引擎才是最合适的。
Oracle的默认事务隔离级别是读已提交,而mysql的默认事务隔离级别是可重复读,根据也无需要,可以把mysql的隔离级别调整到“度已提交”。
“读未提交”和“串行”这两种隔离级别因为脏读和性能的问题,业内用的很少。

mysql事务隔离级别、脏读、幻读的更多相关文章

  1. MySQL进阶15--TCL事务控制语言--建立结束事务/设置断点--默认隔离级别--脏读/幻读/不可重复读

    #TCL事物控制语言 : /* Transaction control language : 事物控制语言 事务: 一个或者一组sql语句组成一个执行单元,这个执行单元要么全部执行,要么全部不执行; ...

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

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

  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事务隔离级别了解一下?

    事务的四大ACID 属性:Atomicity 原子性.Consistency 一致性.Isolation 隔离性.Durability 持久性. 原子性: 事务是最小的执行单位不可分割,强调事务的不可 ...

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

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

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

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

随机推荐

  1. 重启testjenkins的步骤

    在linux下编译caffe的过程中,发生错误,导致linux系统蹦了,没办法,重启linux系统. 之前安装在docker下的jenkins也停掉了. 先启动jenkins的步骤如下: 1.先启动d ...

  2. Laravel 中使用 swoole 项目实战开发案例一 (建立 swoole 和前端通信)

    1 开发需要环境 工欲善其事,必先利其器.在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率. 安装 swoole 拓展包 安装 redis 拓展包 安装 la ...

  3. fsockopen以Socket方式模拟HTTP下载文件

    fsockopen 的功能很强大,比如前面模拟 HTTP 访问,模拟 POST/GET 请求,什么的,这里再举一个例子,那就是下载东西.比如下载 http://www.nowamagic.net//l ...

  4. [TimLinux] JavaScript 如何在html标签的data-*属性使用JSON数据

    1. HTML data-*属性 H5引入的data-*属性,可以在JavaScript通过.dataset.*的方式来获取属性的值,例如: /* HTML标签: * <input id=&qu ...

  5. 马拉车manacher

    目的:线性查找一个串的最长回文子串 时间复杂度:O(n) len[i]表示以i为中心的回文串的半径,mx即为当前计算回文串最右边字符的最大值,p是中心点mid,mx-i和2*p-1关于p对称 http ...

  6. HDU 6118 度度熊的交易计划(网络流-最小费用最大流)

    度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片区能够花费a[i]元生产1个商品,但 ...

  7. 一款简单的C++猜数字游戏(新手必学)

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:1只小弛 废话不多说,直接上代码! #include<bits/s ...

  8. iOS开发 为何 大不如前?原因竟然是这个?

    前言: 近期,社会上对iOS开发行业的负面信息越来越多,并且还被一些黑骗机构的胡诌八扯越描越黑,现在iOS开发按照开发者与公司招聘的数量上来看,是显示的供大于求,但是从各公司的招人计划上来看,明显是供 ...

  9. 每周一练 之 数据结构与算法(Queue)

    这是第二周的练习题,这里补充下咯,五一节马上就要到了,自己的计划先安排上了,开发一个有趣的玩意儿. 下面是之前分享的链接: 1.每周一练 之 数据结构与算法(Stack) 2.每周一练 之 数据结构与 ...

  10. LNMP-Nginx负载均衡

    Nginx负载均衡介绍 Nginx提供负载均衡的模块upstream,这个模块是默认的,不需要重新编译模块.通常情况下,负载均衡一般用于后端两台机器同时提供服务供用户访问,但是用户经常访问的其中一台服 ...