A means that InnoDB uses multi-versioning to present to a query a snapshot of the database at a point in time. The query sees the changes made by transactions that committed before that point of time, and no changes made by later or uncommitted transactions. The exception to this rule is that the query sees the changes made by earlier statements within the same transaction.
一致性读肯定是读取在某个时间点已经提交了的数据,有个特例:本事务中修改的数据,即使未提交的数据也可以在本事务的后面部分读取到。
1. RC 隔离 和 RR 隔离中一致性读的区别
根据隔离级别的不同,一致性读也是不一样的。不同点在于判断是否提交的“某个时间点”:
1)对于RR隔离:
If the transaction is (the default level), all consistent reads within the same transaction read the snapshot established by the first such read in that transaction.
文档中说的是:the first such read in that transaction。实际上实验的结果表明,这里的 the first such read指的是:对同一个表或者不同表进行的第一次select语句建立了该事务中一致性读的snapshot. 其它update, delete, insert 语句和一致性读snapshot的建立没有关系。在snapshot建立之后提交的数据,一致性读就读不到,之前提交的数据就可以读到。
事务的起始点其实是以执行的第一条语句为起始点的,而不是以begin作为事务的起始点的。
实验1:
sesseion A
session B
mysql> set tx_isolation='repeatable-read';
Query OK, 0 rows affected (0.00 sec)
mysql> set tx_isolation='repeatable-read';
Query OK, 0 rows affected (0.00 sec)
mysql> begin;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from t1;
Empty set (0.00 sec)
mysql> insert into t1(c1,c2) values(1,1);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
+----+------+
| c1 | c2 |
+----+------+
| 1 | 1 |
+----+------+
1 row in set (0.00 sec)
上面的实验说明:RR隔离级别下的一致性读,不是以begin开始的时间点作为snapshot建立时间点,而是以第一条select语句的时间点作为snapshot建立的时间点。
实验2:
session A
session B
mysql> set tx_isolation='repeatable-read';
mysql> set tx_isolation='repeatable-read';
mysql> select * from t1;
Empty set (0.00 sec)
mysql> begin;
mysql> select * from t;
mysql> insert into t1(c1,c2) values(1,1);
Query OK, 1 row affected (0.01 sec)
mysql> select * from t1;
Empty set (0.00 sec)
该使用说明:RR隔离级别下的一致性读,是以第一条select语句的执行点作为snapshot建立的时间点的,即使是不同表的select语句。这里因为session A在insert之前对 t 表执行了select,所以建立了snapshot,所以后面的select * from t1 不能读取到insert的插入的值。
实验3:
session A
session B
mysql> set tx_isolation='repeatable-read';
mysql> set tx_isolation='repeatable-read';
mysql> select * from t1;
Empty set (0.00 sec)
mysql> begin;
mysql> select * from t1;
Empty set (0.00 sec)
mysql> select * from t1;
Empty set (0.00 sec)
mysql> insert into t1(c1,c2) values(1,1);
mysql> select * from t1;
Empty set (0.01 sec)