RR 和RC 幻读问题

<pre name="code" class="html">显然 RR 支持 gap lock(next-key lock),而RC则没有gap lock。因为MySQL的RR需要gap lock来解决幻读问题。而RC隔离级别则是允许存在不可重复读和幻读的。所以RC的并发一般要好于RR;
RR 和RC 幻读问题:

幻读:同一个事务中多次执行同一个select, 读取到的数据行发生改变。

也就是行数减少或者增加了(被其它事务delete/insert并且提交)。SERIALIZABLE要求解决幻读问题; 

mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)


Sessio 1:
mysql> select @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
1 row in set (0.00 sec)

mysql> use scan;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1 where id>100;
ERROR 1054 (42S22): Unknown column 'id' in 'where clause'
mysql> select * from t1 where c1>100;
+------+
| c1   |
+------+
|  119 |
|  200 |
|  300 |
|  400 |
| 8999 |
+------+
5 rows in set (0.00 sec)



Sessio 2:
mysql> insert into t1 values(9999);
Query OK, 1 row affected (0.01 sec)

mysql> commit;
Query OK, 0 rows affected (0.00 sec)


Session 1 再次查询:
mysql> select * from t1 where c1>100;
+------+
| c1   |
+------+
|  119 |
|  200 |
|  300 |
|  400 |
| 8999 |
+------+
5 rows in set (0.00 sec)


此时在RR模式下没有幻读



设置隔离级别为RC:
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)


Session 1:
mysql> select @@tx_isolation;
+----------------+
| @@tx_isolation |
+----------------+
| READ-COMMITTED |
+----------------+
1 row in set (0.00 sec)

mysql> use scan;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from t1 where c1>100;
+------+
| c1   |
+------+
|  119 |
|  200 |
|  300 |
|  400 |
| 8999 |
| 9999 |
+------+
6 rows in set (0.00 sec)



Session 2:
mysql> select * from t1;
+------+
| c1   |
+------+
|   33 |
|   34 |
|   87 |
|   89 |
|  119 |
|  200 |
|  300 |
|  400 |
| 8999 |
| 9999 |
+------+
10 rows in set (0.00 sec)

mysql> insert into t1 values(7777777);
Query OK, 1 row affected (0.01 sec)

Session 1再次查询:
mysql> select * from t1 where c1>100;
+---------+
| c1      |
+---------+
|     119 |
|     200 |
|     300 |
|     400 |
|    8999 |
|    9999 |
| 7777777 |
+---------+
7 rows in set (0.00 sec)

说明RC模式下,可以幻读



                
在MVCC(多版本并发控制)中,RR(可重复读)和RC(读已提交)级别都使用了MVCC来进行不加锁的读。然而,RRRC之间存在一些区别。 在RC模式下,每次读操作都会生成一个ReadView,这个ReadView会记录在开始读取时数据库的状态。这意味着在同一事务中,不同的查询可能会返回不同的结果,因为其他事务可能已经修改了数据。这就是为什么RC不能解决幻读的原因。 相比之下,在RR模式下,每个事务在开始时都会生成一个快照(Snapshot)来获取数据库的状态。这个快照会一直被事务使用,直到事务结束。因此,在RR模式下进行的同一查询会始终返回相同的结果,即使在事务执行期间有其他事务修改了数据。这就是为什么RR可以解决幻读的原因。 总结一下,RR模式下使用的快照能够保证在整个事务过程中查询到的数据始终是一致的,而RC模式下每次读操作都生成一个ReadView,因此可能会受到其他事务的修改影响,导致查询结果不一致。这就是RRRC在MVCC中的区别。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [MVCC下的RRRC级别的区别和实现](https://blog.csdn.net/qq_35634181/article/details/113280233)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scan724

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值