2012-01-30 182 views
3

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

1)事务T1从排R1中读取数据,

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

3)T1修改数据读在#1中提交数据到r1

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

我试过这与Hibernate(隔离级别设置为RR),并看到了上述行为。

为什么然后说为了RR隔离,我们不会得到第二个丢失的更新问题?

回答

2

您可以推断在您在本测试中使用的MySQL版本,执行并没有真正符合重复读,就像你在你的另一个问题说,因为如果你做

事务T2读取行相同的数据R1

再次在步骤4中,而不是

T2修改数据读在#2和数据提交到R1。

则T2会读它通过T1在步骤中保存的值3 所以你不必repeteable在第一次读,所以它不与更新丢失repeteable读的情况。

ANSI SQL-92根据现象定义隔离级别:肮脏的 读取,非重复读取和模型。

而不是像你这样的锁而言,在第一when you said

想到现在,我的理解是,RR采用共享读锁和排他写 锁

这是因为

ANSI SQL隔离设计人员寻求一个定义,该定义允许多个 不同的实现,而不仅仅是锁定。

事实上,其中一个例子是READ_COMMITED implementation from SQL SERVER

如果READ_COMMITTED_SNAPSHOT设置为OFF(缺省值),该数据库 引擎使用共享锁防止而当前事务正在运行的读取操作修改 行其他交易。 [...]

如果READ_COMMITTED_SNAPSHOT设置为ON时,数据库引擎使用行 版本来呈现每个语句事务一致 快照中的数据,因为它在语句开始时就存在。 锁不用于保护数据免受更新其他 交易

丢失的更新是不是这个现象之一,但在A Critique of ANSI SQL Isolation Levelsthe other question指出的Argeman解释说repeteable读确保不丢失更新:

P1 =非repeteable读取 P4 =丢失更新 P2的不严谨的解释(指定了一个现象,可能导致 一个异常)是

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

P2的严格解释(指定实际ANOM ALY),称为A1是

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

虽然丢失更新的解释是

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

你目前正处于形式的情况下:

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

起初似乎是没有不可重复读取的情况,实际上t1会在整个事务中读取相同的x值。

但是,如果我们关注t2并反转数字,我们可以看到这显然是不可重复读取的情况。

A4:R1 [X] ... R2 [X] ... W1 [X] ... ... C1 W2 [X] ... C2

A4:R1 [X] ... W2 [X] ... C2 ... W1 [X] ... C1(倒置可读性更好的数字)

P2:R1 [X] ... W2 [X] ...((C 1或a1)和(C2 或a2)以任何顺序)