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. MySQL双主+keepalived实现高可用实现(热备)

    环境:centos6.7 最小化安装 192.168.100.152 master 主192.168.100.153 slave 从192.168.100.132 v_ip 浮动IP 配置ssh密码登 ...

  2. 【Android - 控件】之MD - CoordinatorLayout的使用

    CoordinatorLayout是Android 5.0新特性——Material Design中的一个布局控件,主要用来协调各个子视图之间的工作,也可以用来作为顶部布局.CoordinatorLa ...

  3. Tomcat连接器详解

    1.连接器等同于nginx中的引擎. 2.tomcat连接器有三种运行模式bio.nio.apr . (1)bio(blocking I/O,阻塞式I/O操作) 1)表示tomcat使用的是传统的ja ...

  4. C# MVC 过滤器

    APS.NET MVC中(以下简称“MVC”)的每一个请求,都会分配给相应的控制器和对应的行为方法去处理,而在这些处理的前前后后如果想再加一些额外的逻辑处理.这时候就用到了过滤器. MVC支持的过滤器 ...

  5. 一条数据的HBase之旅,简明HBase入门教程3:适用场景

    [摘要] 这篇文章继HBase数据模型之后,介绍HBase的适用场景,以及与一些关键场景有关的周边技术生态,最后给出了本文的示例数据 华为云上的NoSQL数据库服务CloudTable,基于Apach ...

  6. 了解BootLoader——基于MPC5744P Bootloader例程

    一.BootLoader的作用:BootLoader是固化在PFlash中的一个程序,其作用可以分为两部分:boot和load. (1)boot:MCU上电时首先会运行BootLoader程序(因为它 ...

  7. [NACOS HTTP-GET] The maximum number of tolerable server reconnection errors has been reached

    错误的意思是:已达到可容忍的服务器重连接错误的最大数目.有两个解决思路:一个将这个值设置的更大:然后是排查自己连接服务哪儿出了问题.先说在哪儿设置这个值:在拉取nacos服务的注解配置中,添加一个属性 ...

  8. apache thrift 和 apache jersey 记录

    几篇好的入门文档链接: 1. Hello World by Thrift Using Java 2. Thrift 实例 Helloworld 3. Thrift版的Hello World 4. Th ...

  9. 一道题反映Java的类初始化过程

    Java的类初始化过程: 1. 父类的static成员变量,static语句块. 2. 子类的static成员变量,static语句块. 3. 父类的普通成员变量,构造函数. 4. 子类的普通成员变量 ...

  10. luogu P1976 鸡蛋饼

    题目背景 Czyzoiers 都想知道小 x 为什么对鸡蛋饼情有独钟.经过一番逼问,小 x 道出了实情:因为他喜欢圆. 题目描述 最近小 x 又发现了一个关于圆的有趣的问题:在圆上有 2N 个不同的点 ...