我有一个可重复读取的隔离级别,我正在制作一个:
Select * From example
的查询。我在https://dev.mysql.com/doc/refman/5.7/en/innodb-locks-set.html中读到了从查询中选择...使用来自快照的一致读取,因此在行或表上没有设置锁定。这是否意味着,在select之后但在select查询结束之前启动的更新,插入或删除仍然能够运行,即使修改不会显示在选择结果中?
答案 0 :(得分:2)
基本上,是的,情况就是这样,有些复杂。
默认情况下,在repeatable read
中,select ... from ...
不会对基础数据设置任何锁定并建立快照。
如果另一个事务更改了基础数据,则如果在第一个事务的范围内再次选择了相同的记录,则不会反映这些更改。到目前为止一切都很好。
但是,如果您的第一个事务修改了在建立快照后受其他已提交事务影响的记录,则其他事务完成的那些修改也将对第一个事务可见,因此您的快照可能在之后不一致所有
有关此功能的更多详细信息,请参阅MySQL手册的Consistent Nonlocking Reads章节中的第1个注释部分。
答案 1 :(得分:2)
是的,您可以在现有交易持有数据的可重复读取快照时更新/插入/删除。
这是由多版本并发控制或MVCC实现的。
这是一种奇特的方式,说RDBMS保留了同一行的多个版本,因此可重复读取的快照可以继续阅读旧版本,只要它们需要(也就是说,因为他们的交易快照存在)。
如果存在由事务启动后提交的事务创建的行版本,则您不应该能够看到该行版本。每个行版本在内部保留有关创建它的事务的一些元数据,并且每个事务都知道如何使用它来确定它是否应该看到行版本。
最终,所有可能对旧行版本感兴趣的交易完成,MVCC可以"清理"过时的行版本。