在mysql里,有两个“视图”的概念:
1、view:它是一个用查询语句定义的虚拟表,在调用的时候执行查询语句并生成结果。创建视图的语法是create view...,而它的查询方法与表一样。
2、InnoDB在实现MVCC时用到的一致性读视图,即consistent read view,用于支持RC(read committed,读提交)和RR(Repeatable Read,可重复读)隔离级别的实现。
它没有物理结构,作用是事物执行期间用来定义“我能看到什么数据”。
“快照”在MVCC里是怎么工作的?
一个数据版本,对于一个事物视图来说,除了自己的更新总是可见以外,有三种情况:
1、版本未提交,不可见;
2、版本已提交,但是是在视图创建后提交的,不可见;
3、版本已提交,而且是在视图创建前提交的,可见。
规则:更新数据都是先读后写的,而这个读,只能读当前的值,称为“当前读”。
mysql> select k from t where id=1 lock in share mode;
mysql> select k from t where id=1 for update;
事物的可重复读的能力是怎么实现的?
可重复读的核心就是一致性读(consistent read);而事物更新数据的时候,只能用当前读。如果当前的记录的行锁被其他事物占用的话,就需要进入锁等待。
读提交的逻辑和可重复读类似,他们最主要的区别是:
1、在可重复读隔离级别下,只需要在事物开始的时候创建一致性视图,之后事物里的其他查询都共用这个一致性视图;
2、在读提交隔离级别下,每一个语句执行前都会重新算出一个新的视图。
小结
InnoDB的行数据有多个版本,每个数据版本有自己的row trx_id,每个事物或者语句都有自己的一致性视图。普通查询语句是一致性读,一致性读会根据row trx_id和一致性视图确定数据版本的可见性。
1、对于可重复读,查询只承认在事物启动前就已经提交完成的数据;
2、对于读提交,查询只承认在语句启动前就已经提交完成的数据。
而当前都,总是读取已经提交完成的最新版本。
为什么表结构不支持“可重复读”?
这是因为表结构没有对应的行数据,也没有row trx_id,因此只能遵循当前读的逻辑。
网友评论