暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Mysql事务的隔离机制(三)

氷泠之路 2021-05-11
1029
这篇文章我们来仔细谈一谈封锁协议与隔离级别.

封锁协议就是在用X锁或S锁时制定的一些规则,比如锁的持续时间,锁的加锁时间等.不同的封锁协议对应不同的隔离级别.事务的隔离级别一共有4种,由低到高分别是Read uncommitted,Read committed,Repeatable read,Serializable,分别对应的相应的封锁协议等级.

1.一级封锁协议




    一级封锁协议对应的是Read uncommitted隔离级别,Read uncommitted,读未提交,一个事务可以读取另一个事务未提交的数据,这是最低的级别.一级封锁协议本质上是在事务修改数据之前加上X锁,直到事务结束后才释放,事务结束包括正常结束(commit)与非正常结束(rollback).

    
一级封锁协议不会造成更新丢失,但可能引发脏读,幻读,不可重复读.

设置手动提交与事务隔离等级为read uncommited,并开启事务(注意要先设置事务等级再开启事务).

    

    set autocommit=0;
    set session transaction isolation level read uncommitted;
    start transaction;
           

    (中间有一行打多了一个t可以忽略.....)


    (1) 引发脏读

    在一个事务中修改表中的值,不提交,另一个事务可以select到未提交的值.


    出现了脏读.

    (2) 引发幻读

    在一个事务中插入一条数据,提交.


    另一事务中select时没有,准备insert,但是insert时却提示已经存在.引发幻读.


    (3) 引发不可重复读

    未操作提交前:
    另一事务修改并提交:
    再次读:
    引发不可重复读.

    2.二级封锁协议



    二级封锁协议本质上在一级协议的基础上(在修改数据时加X锁),在读数据时加上S锁,读完后立即释放S锁,可以避免脏读.但有可能出现不可重复读与幻读.二级封锁协议对应的是Read committed与Repeatable Read隔离级别.先设置隔离等级.
      set session transaction isolation level read committed;

      (1) Read committed

      Read committed,读提交,读提交可以避免脏读,但可能出现幻读与不可重复读.

      a.避免脏读

               开启一个事务并更新值,在这个事务中money=100(更新后).

              另一事务中money为未更新前的值,这就避免了脏读.


              注意,事实上脏读在read committed隔离级别下是不被允许的,但是mysql不会阻塞查询,而是返回未修改之前数据的备份,这种机制叫MVCC机制(多版本并发控制).

      b.引发幻读

              在一个事务中插入数据并提交.


              另一事务中不能插入"不存在"的数据,出现幻读.



      c.引发不可重复读

              事务修改并提交前:


                         事务修改并提交:

                 出现不可重复读.

      (2) Repeatable read

      Repeatable read比Read committed严格一点,是Mysql的默认级别,读取过程更多地受到MVCC影响,可防止不可重复读与脏读,但仍有可能出现幻读.

      a.避免脏读

              在一个事务中修改数据,不提交.


              另一事务中两次select的结果都不变,没有出现脏读.


      b.避免不可重复读

              一个事务修改数据并提交.

              另一事务中select的结果没有发生改变,即没有出现不可重复读.


      c.引发幻读

              同理,一个事务插入一条数据并提交.

              另一个事务插入时出现幻读.



      3. 三级封锁协议


      三级封锁协议,在一级封锁协议的基础上(修改时加X锁),读数据时加上S锁(与二级类似),但是直到事务结束后才释放S锁,可以避免幻读,脏读与不可重复读.三级封锁协议对应的隔离级别是Serializable.先设置Serializable隔离级别.


        set session transaction isolation level serializable

        a.避免脏读

                设置事务隔离等级后开启事务并update,发现堵塞.从而避免了脏读.

        b.避免幻读

                插入时直接阻塞,避免了幻读.



        c.避免不可重复读

            在脏读的例子中可以知道,update会被堵塞,都不能提交事务,因此也避免了不可重复读.


        4.两段锁协议



        事务必须分为两个阶段对数据进行加锁与解锁,两端锁协议叫2PL(不是2PC),所有的加锁都在解锁之前进行.


        (1) 加锁

        加锁会在更新或者

          select *** for update
          *** lock in share mode

          时进行.


          (2) 解锁

          解锁在事务结束时进行,事务结束包括rollback与commit.


              

          文章转载自氷泠之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论