mysql事务隔离级别及测试

  一.数据库事务

        何为数据库事务( transaction)?事务是指访问并可能操作各种数据项的一个数据库操作序列,这些操作要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务由事务开始与事务结束之间执行的全部数据库操作组成。

        数据库管理系统DBMS)在写入或更新资料的过程中,为保证事务(transaction)是正确可靠的,所必须具备的四个特性:原子性(atomicity,或称不可分割性)、一致性(consistency)、隔离性(isolation,又称独立性)、持久性(durability)

二.ACID(事务处理的标准特性)

  1. 原子性(Atomicity)

         一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被恢复(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

    2. 一致性(Consistency) 

        在事务开始之前和事务结束以后,数据库的完整性没有被破坏。且数据库中的数据始终都是保持一致的。

    3.  隔离性(Isolation)     

       通常来说一个事务所做的修改在提交以前,对其他事务是不可见的。但是可以设置事务的隔离级别,来觉得这个不可见是否被允许。事务隔离分为不同级别,包括读未提交(Read uncommitted)读提交(read committed)可重复读(repeatable read)串行化(Serializable)

    4. 持久性(Durability)

        事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

三.事务的隔离级别

        在SQL标准中定义了四种隔离级别,每一种级别都规定了一个事务中所做的修改,哪些在事务内和事务之间是可见的、哪些是不可见的。较低级别的隔离通常可以执行更高的并发,系统开销也更低。其各级别的特性入下图:  

    

  1. 读未提交-Read uncommitted
  2. 读已提交-Read committed
  3. 可重复读-Repeatable read–MySQL
  4. 序列化-Serializable

 

 注意:mysql的InnoDB的可重复读,解决了幻读的问题。文档如下:

 ”可重复读“隔离级别下MySQL是如何解决幻读问题的-CSDN博客

   1.理解脏读、不可重复读、幻读

               如上图所示,不同的隔离级别,对多个事务读取的数据而言,会造成各种不同的影响。其主要为表现为:脏读不可重复读幻读。其具体解释如下。

              脏读:A事务读取到了B事务已添加或修改但还未提交的数据,如果B事务后期回滚了,那么A事务就读到了脏数据。

             不可重复读:   同一个事务中,对于同一数据,执行完全相同的select语句时可能看到不一样的结果。

               幻读:幻读,并不是说两次读取获取的结果集不同,幻读侧重的方面是某一次的 select 操作得到的结果所表征的数据状态无法支撑后续的业务操作。更为具体一些:select 某记录是否存在,不存在,准备插入此记录,但执行 insert 时发现此记录已存在,无法插入,此时就发生了幻读。幻读参考文档:MySQL幻读 - 简书滑动验证页面

 2.事务的隔离级别测试。  

测试首先要设置数据库的个理级别,隔离级别分为全局和当前事务两种,设置方法如下:

  设置事务全局隔离级别:set global transaction isolation level  read UNCOMMITTED;
  设置事务当前会话隔离级别:set session transaction isolation level  read UNCOMMITTED;  

查看当前隔离级别如下:

select @@transaction_isolation;
show variables like 'transaction_isolation';

          a.读未提交(READ-UNCOMMITTED)

                      该隔离级别最低会产生脏读、不可重复读、幻读。其中脏读测试如下。  

          b.读已提交(READ-COMMITTED)

                     该隔离级别不会产生脏读(a事务未提交的数据,b事务读不到);但是会产生不可重复读、幻读。其中不可重复读测试如下。

                         

幻读测试如下:

 如图。发现A事务第一次读,和第二次读不一样。就发生了幻读。或者在事务2里面去做删除张三。这个时候事务A第一次读的时候有张三的数据,第二次读就会没有张三。事务A会产生幻觉。

          c. 可重复读(Repeatable-Read)

                该隔离级别不会产生脏读(a事务未提交的数据,b事务读不到);不会产生不可重复读、但是会产生幻读(通过间隙锁解决幻读,MVCC。其中不会产生不可重复读测试如下。

 不会产生幻读测试如下:

        1.快照读(select * from test )测试,看执行情况()。

                快照读是通过MVCC原理解决的幻读,测试如下:

        2.当前读(selectd *from test  for update )测试,看执行情况。

                当前读是通过间隙锁解决幻读,测试如下:

 由图可知。数据库里数据(1,2,3,10)语句select * from tb_isolation_level where id >=10 for update ;会对10以后的间隙枷锁。3 -10 这个间隙不会加锁,所以insert ID= 6的时候不会阻塞,而ID=10 的数据 就会阻塞直至A事务提交。

         d.序列化-Serializable

(同表同行数据 锁定)

(同表不同行数据 也是能读不能修改) 

 (同一行数据操作)

 (两行数据操作)

总结:

mysql 的InnoDB,在隔离级别为:可重复读(Repeatable read)时,不会产生幻读(通过间隙锁解决了幻读问题。)

               

      

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值