4

使用可重复的读取隔离级别,仍然有可能丢失更新(第二次丢失更新问题)。例如在隔离级别设置为 RR 的场景中:

1) 事务 t1 从行 r1 读取数据,

2) 事务 t2 从行 r1 读取相同的数据,

3)t1修改#1中读取的数据,并将数据提交给r1

4) t2 修改#2 中读取的数据,并将数据提交给 r1。t1 的更新丢失

我用 Hibernate(隔离级别设置为 RR)尝试了这个,并看到了上面提到的行为。

那么为什么说使用 RR 隔离我们不会遇到第二次丢失更新的问题呢?

4

2 回答 2

3

您可以推断,在您在此测试中使用的 MySQL版本中,实现并不真正符合 Repeatable Read,就像您在另一个问题中所说的那样,因为如果您已经完成

事务 t2 从行 r1 读取相同的数据

再次在步骤 4 中,而不是

t2 修改#2 中读取的数据并将数据提交给 r1。

那么 t2 将在步骤 3 中读取 t1 保存的值。所以你一开始没有可重复读取,所以这不是可重复读取丢失更新的情况。

ANSI SQL-92 根据现象定义了隔离级别:Dirty Reads、Non-Repeatable Reads 和 Phantoms。

而不是像你一开始说的那样的锁

现在,据我了解,RR 使用共享读锁和独占写锁

这是因为

ANSI SQL Isolation designers sought a definition that would admit many different implementations, not just locking.

In fact one example of this is the READ_COMMITED implementation from SQL SERVER.

If READ_COMMITTED_SNAPSHOT is set to OFF (the default), the Database Engine uses shared locks to prevent other transactions from modifying rows while the current transaction is running a read operation. [...]

If READ_COMMITTED_SNAPSHOT is set to ON, the Database Engine uses row versioning to present each statement with a transactionally consistent snapshot of the data as it existed at the start of the statement. Locks are not used to protect the data from updates by other transactions.

The lost updates is not one of this phenomena, but in A Critique of ANSI SQL Isolation Levels pointed out by Argeman in the other question is explained that repeteable read guarantees no lost updates:

P1 = Non-repeteable reads P4 = Lost updates The loose interpretation of P2 (specifies a phenomenon that might lead to an anomaly) is

P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)

The strict interpretation of P2 (specifies an actual anomaly), called A1 is

A2: r1[x]...w2[x]...c2...r1[x]...c1

While the interpretation of lost updates is

P4: r1[x]...w2[x]...w1[x]...c1

The case that you present is in the form of:

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

At first it seems that is a case that doesn't have non-repeteable reads, in fact the t1 will always read the same value of x along the whole transaction.

But if we focus on the t2 and invert the numbers we can see that is clearly a case of non-repeteable read.

A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2

A4: r1[x]...w2[x]...c2...w1[x]...c1 (with the numbers inverted for better readability)

P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)

于 2016-01-17T02:31:58.587 回答
0

我曾用 MySQL 尝试过上述实验,看起来 MySQL 实现了不同的 RR 概念:MySQL 可重复读取和丢失更新/幻读

于 2012-04-06T08:36:59.477 回答