zoukankan      html  css  js  c++  java
  • 脏读---不可重复度----可重复度----幻读现象的解释

    RC模式下出现的脏读现象

    有一张表如下:
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 王五 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    我们开始一个事务
    mysql> begin;
    mysql> update t1 set name='大虎' where age=17;
    此时,我们不执行提交,在另一会话查看
    select * from t1;
    mysql> select * from t1;
    +------+--------+------+
    | id   | name   | age  |
    +------+--------+------+
    |    1 | 张三   |   25 |
    |    4 | 李四   |   20 |
    |    6 | 大虎   |   17 |
    |    9 | 大刀   |   27 |
    |   15 | 赵虎   |   35 |
    |   20 | 王强   |   32 |
    +------+--------+------+
    数据已经发生改变了,这就是脏读了
    事务还不确定提不提交,就可以读到所以这种模式不适合
    例子解释:取款的时候,还没有点确认取款,但是查余额时,发现已经少了!所以这种模式一般不用
    

    RU模式可防止脏读,但是会出现不可重复读和幻读

    有一张表如下:
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 王五 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    我们开始一个事务
    mysql> begin;
    mysql> update t1 set name='大虎' where age=17;
    此时,我们不执行提交,在另一会话查看
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 王五 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    数据并未发生变化,所以就防止了脏读现象
    

    RC模式下的不可重复读现象

    有一张表如下:
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 王五 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    我们开始一个事务
    mysql> begin;
    mysql> update t1 set name='大虎' where age=17;
    并且提交
    mysql>commit;
    此时,我们去查看数据,数据发生了变化
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 大虎 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    这种情况看似很好,但是我们在执行命令
    mysql> update t1 set name='大黄' where age=17;
    并且提交
    mysql>commit;
    此时,我们去查看数据,数据发生了变化
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 大黄 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    此时数据又发生了变化
    这种情况下,我们不知道我们查询的结果是什么,这就是不可重复读的现象了
    在这种模式下,一般的互联网公司是可以接受的,但是金融行业不能用这种模式
    为什么金融行业不能用于这种模式?
    银行12月31做年底盘点,要把数据卡在23:59:59,在RC模式下去统计的时候,这个时候不能因为要统计而把业务观点,但是由于是在RC模式下,统计的结果不停在变,有可能把这个时间点以后的数据统计进来了,所以金融行业不能用这种模式,因此,就要用RR模式
    

    RC模式下的幻读现象

    有一张表如下:
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 王五 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    我们开始一个事务
    mysql>begin;
    mysql>update t1 set age=23 where age<25;
    这个事务还没有提交,在另一个窗口又执行了一个事务
    mysql>insert into t1 values(32,'小强','17');
    并且提交了
    mysql>commit;
    这个时候mysql>update t1 set age=23 where age<25;也提交了
    我们再去查数据的时候可以看到,里面有一行数据age=17,这与我们预想的结果不一样
    这种现象就是幻读现象了
    在RC级别下,可以减轻GAP+NextLock锁的问题,但是会出现幻读现象,一般在为了读一致性会在正常select后添加for update语句.但是,请记住执行完一定要commit 否则容易出现锁等待比较严重.
    

    RR模式下解决幻读现象和不可重复读现象

    有一张表如下:
    mysql> select * from t1;
    +----+------+-----+
    | id | name | age |
    +----+------+-----+
    |  1 | 张三 |  25 |
    |  4 | 李四 |  20 |
    |  6 | 王五 |  17 |
    |  9 | 大刀 |  27 |
    | 15 | 赵虎 |  35 |
    | 20 | 王强 |  32 |
    +----+------+-----
    我们开始一个事务
    mysql>begin;
    mysql>update t1 set age=23 where age<25;
    并且提交了
    我们在另一窗口查看的时候,并不会出现新改的这一行,这样就解决了不可重复度现象
    通俗点讲就是:我们打开一个窗口查询时,里面的表的数据会永远保持此时的状态,不管在别的窗口怎么改,在此窗口读到的还是我们打开窗口时的状态!
    这种模式就是利用undo快照技术+GAP(间隙锁)+nextlock(下一键锁)(MVCC实际上就是在每一个会话开启时都会生成一个快照),将来在读取的时候,在别的会话不管怎么改,读取的都是起始时候的数据
    解决幻读现象就是因为在这种模式下有间隙锁和下一键锁,
    A事务在修改的时候,B事务插入数据根本就插入不了
    
    学习的进阶之路
  • 相关阅读:
    android 学习笔记1- 应用程序的资源管理
    idea shortcut
    关于layou以及layout 上的控件
    java 之深拷贝与浅拷贝
    Java中static静态方法可以继承吗?可以被重写吗?
    String StringBuff StringBuilder 使用。
    linux 中断
    设备类class理解
    linux 内核符号
    QT 调试输出格式
  • 原文地址:https://www.cnblogs.com/yufenchi/p/12961777.html
Copyright © 2011-2022 走看看