![mark](https://img.zouchanglin.cn///20200227/9xbkj74TxjVu.png)
在之前为文章《分析事务隔离的实现》中我们提到:如果是可重复读隔离级别,事务T启动的时候会创建一个视图 read-view,之后事务 T 执行期间,即使有其他事务修改了数据,事务 T 看到的仍然跟在启动时看到的一样。也就是说,一个在可重复读隔离级别下执行的事务,好像与世无争,不受外界影响。但是,我在介绍MySQL锁机制的文章中《探究MySQL锁机制》 的时候,一个事务要更新一行,如果刚好有另外一个事务拥有这一行的行锁,它会被锁住,进入等待状态。问题是,既然进入了等待状态,那么等到这个事务自己获取到行锁要更新数据的时候,它读到的值又是什么呢?
开始事务的两种方式
需要注意的是:begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作InnoDB 表的语句,事务才真正启动。 如果你想要马上启动一个事务,可以使用transaction with consistent snapshot 这个命令!
第一种启动方式,一致性视图是在第执行第一个快照读语句时创建的;
第二种启动方式,一致性视图是在执行 start transaction with consistent snapshot 时创建的;
事务 C 没有显式地使用 begin/commit,表示这个 update 语句本身就是一个事务,语句完成的时候会自动提交。事务 B 在更新了行之后查询 ; 事务 A 在一个只读事务中查询,并且时间顺序上是在事务 B 的查询之后。但是结果却是:事务 B 查到的 k 的值是 3,而事务 A 查到的 k 的值是 1
![mark](https://img.zouchanglin.cn///20200227/m8uKq072shnE.png)
按照我们想象的情况应该是如下所示:
![mark](https://img.zouchanglin.cn///20200227/YFyGJrShejou.png)
最终得到的结果是事务A查询的结果为1,事务B查询的结果是2,但是为什么事务B查询后为3呢??
需要注意的是,在 MySQL 里,有两个视图
的概念:
1、一个是view,它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是 create view … ,而它的查询方法与表一样。
2、另一个是 InnoDB 在实现 MVCC(Multi-Version Concurrency Control,多版本并发控制)时用到的一致性读视图,即 consistent read view,用于支持 RC(Read Committed&#x