“可重复读”和“快照隔离”有什么区别?

17

可重复读是一种更高的隔离级别,除了保证读提交级别的内容外,还保证任何已读取的数据不会更改。如果事务再次读取相同的数据,则会发现之前读取的数据仍在原处,未更改且可供读取。

这似乎与快照隔离级别非常相似。

可重复读与快照隔离级别有何不同?

3个回答

26

“快照”保证事务内的所有查询将看到事务开始时的数据。

“可重复读”仅保证如果事务内的多个查询读取了相同的行,则每次它们都将看到相同的数据。(因此,不同的行可能在不同的时间被拍摄,取决于事务首次检索它们的时间。如果插入新行,则稍后的查询可能会检测到它们。)


1
从https://www.cockroachlabs.com/blog/consistency-model/了解到,可重复读允许幻象,这意味着“如果一个事务执行一个查询两次,要求匹配某个条件的行,则第二次执行可能返回比第一次更多的行。例如,像select * from orders where value > 1000这样的语句第一次可能返回订单(a,b,c),第二次可能返回订单(a,b,c,d)”。似乎不需要多个表。 - Javier
1
@Javier: 感谢您的评论!我明白我的括号注释可能会让人感到困惑。我现在已经进行了调整,并且采纳了您提供的非常有帮助的例子。 :-) - ruakh

3

快照隔离在PostgreSQL和MySQL中称为“可重复读”,在Oracle DB中称为“可序列化”。IBM DB2使用“可重复读”来指代串行化。

SQL标准没有快照隔离的概念,这是命名混乱的原因。

因此,没有人真正知道可重复读意味着什么。但是,可以合理地假设它们是相同的东西。


0
假设一个事务从时间t1开始,
在快照隔离级别下:当一个事务从时间t1开始,它会感知到整个数据库在t1时刻的一致快照。因此,如果在t1、t1+d或者更晚的时间读取一行数据,所获取的数据将始终与该行在t1时刻的状态一致。
但是在可重复读隔离级别下,情况有所不同。如果事务从时间t1开始,但并不立即读取某一行数据。现在,如果另一个事务修改了该行数据,然后我们的事务在t1+d时刻首次读取它,它将看到修改后的值。从那时起,在事务期间对该行的任何后续读取(比如在t1+d+e或更晚的时间)都将显示与t1+d时刻相同的值。 这确保了一旦读取了一行数据,其值在整个事务期间保持一致。但是,除非在t1时刻读取了该行数据,否则不能保证该行的值与事务开始时(t1时刻)的状态一致。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接