【58沈剑 架构师之路】InnoDB,快照读,在RR和RC下有何差别?

快照读(Snapshot Read)数据库

MySQL数据库,InnoDB存储引擎,为了提升并发,使用MVCC机制,在并发事务时,经过读取数据行的历史数据版本,不加锁,来提升并发的一种不加锁一致性读(Consistent Nonlocking Read)。并发

 

读提交(Read Committed)高并发

  • 数据库领域,事务隔离级别的一种,简称RCspa

  • 它解决“读脏”问题,保证读取到的数据行都是已提交事务写入的3d

  • 它可能存在“读幻影行”问题,同一个事务里,连续相同的read可能读到不一样的结果集事务

 

可重复读(Repeated Read)get

  • 数据库领域,事务隔离级别的一种,简称RRit

  • 它不但解决“读脏”问题,还解决了“读幻影行”问题,同一个事务里,连续相同的read读到相同的结果集io

 

读提交(RC),可重复读(RR)两个不一样的事务的隔离级别下,快照读有什么不一样呢?date

 

先说结论

  • 事务总可以读取到,本身写入(update /insert /delete)的行记录

  • RC下,快照读老是能读到最新的行数据快照,固然,必须是已提交事务写入的

  • RR下,某个事务首次read记录的时间为T,将来不会读取到T时间以后已提交事务写入的记录,以保证连续相同的read读到相同的结果集

画外音:能够看到

(1)和并发事务的开始时间不要紧,和事务首次read的时间有关;

(2)因为不加锁,和互斥关系也不大;

 

这些就能解答《InnoDB的快照读,到底和什么相关?》中的问题了,InnoDB表:

t(id PK, name);
 
表中有三条记录:
1, shenjian
2, zhangsan
3, lisi

 

case 1,两个并发事务A,B执行的时间序列以下(A先于B开始,B先于A结束):

A1: start transaction;
         B1: start transaction;
A2: select * from t;
         B2: insert into t values (4, wangwu);
A3: select * from t;
         B3: commit;
A4: select * from t;

 

提问1:假设事务的隔离级别是可重复读RR,事务A中的三次查询,A2, A3, A4分别读到什么结果集?

 

回答:RR下

(1)A2读到的结果集确定是{1, 2, 3},这是事务A的第一个read,假设为时间T;

(2)A3读到的结果集也是{1, 2, 3},由于B尚未提交;

(3)A4读到的结果集仍是{1, 2, 3},由于事务B是在时间T以后提交的,A4得读到和A2同样的记录;


提问2:假设事务的隔离级别是读提交RC,A2, A3, A4又分别读到什么结果集呢?

 

回答:RC下

(1)A2读到的结果集是{1, 2, 3};

(2)A3读到的结果集也是{1, 2, 3},由于B尚未提交;

(3)A4读到的结果集仍是{1, 2, 3, 4},由于事务B已经提交;

 

case 2,仍然是上面的两个事务,只是A和B开始时间稍有不一样(B先于A开始,B先于A结束):

         B1: start transaction;

A1: start transaction;

A2: select * from t;
         B2: insert into t values (4, wangwu);
A3: select * from t;
         B3: commit;
A4: select * from t;

 

提问3:假设事务的隔离级别是可重复读RR,事务A中的三次查询,A2, A3, A4分别读到什么结果集?

提问4:假设事务的隔离级别是读提交RC,A2, A3, A4的结果集又是什么呢?
 

回答:事务的开始时间不同,不会影响“快照读”的结果,因此结果集和case 1同样。

 

case 3,仍然是并发的事务A与B(A先于B开始,B先于A结束):

A1: start transaction;
         B1: start transaction;
         B2: insert into t values (4, wangwu);
         B3: commit;
A2: select * from t;

 

提问5:假设事务的隔离级别是可重复读RR,事务A中的A2查询,结果集是什么?

提问6:假设事务的隔离级别是读提交RC,A2的结果集又是什么呢?

 

回答:在RR下,

A2是事务A的第一个read,假设为时间T,它能读取到T以前提交事务写入的数据行,故结果集为{1, 2, 3, 4}。在RC下,没有疑问,必定是{1, 2, 3, 4}。

 

case 4,事务开始的时间再换一下(B先于A开始,B先于A结束):

         B1: start transaction;

A1: start transaction;

         B2: insert into t values (4, wangwu);

         B3: commit;
A2: select * from t;

 

提问7:假设事务的隔离级别是可重复读RR,事务A中的A2查询,结果集是什么?

提问8:假设事务的隔离级别是读提交RC,A2的结果集又是什么呢?

 

回答:事务的开始时间不同,不会影响“快照读”的结果,因此结果集和case 3同样。

相关文章
相关标签/搜索