码迷,mamicode.com
首页 > 其他好文 > 详细

脏读---不可重复度----可重复度----幻读现象的解释

时间:2020-05-26 01:30:57      阅读:75      评论:0      收藏:0      [点我收藏+]

标签:窗口查看   金融行业   sel   date   undo   互联网   --   mys   行业   

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事务插入数据根本就插入不了

脏读---不可重复度----可重复度----幻读现象的解释

标签:窗口查看   金融行业   sel   date   undo   互联网   --   mys   行业   

原文地址:https://www.cnblogs.com/yufenchi/p/12961777.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!