使用可重复读取隔离级别,仍有可能丢失更新(第二次丢失更新问题)。例如。在与隔离级别的场景设置为RR:可重复读取和第二次丢失更新问题
1)事务T1从排R1中读取数据,
2)事务T2从行r1读取相同的数据,
3)T1修改数据读在#1中提交数据到r1
4)t2修改在#2中读取的数据并将数据提交给r1。 t1的更新丢失
我试过这与Hibernate(隔离级别设置为RR),并看到了上述行为。
为什么然后说为了RR隔离,我们不会得到第二个丢失的更新问题?
使用可重复读取隔离级别,仍有可能丢失更新(第二次丢失更新问题)。例如。在与隔离级别的场景设置为RR:可重复读取和第二次丢失更新问题
1)事务T1从排R1中读取数据,
2)事务T2从行r1读取相同的数据,
3)T1修改数据读在#1中提交数据到r1
4)t2修改在#2中读取的数据并将数据提交给r1。 t1的更新丢失
我试过这与Hibernate(隔离级别设置为RR),并看到了上述行为。
为什么然后说为了RR隔离,我们不会得到第二个丢失的更新问题?
我试过上述实验与MySQL,看起来像MySQL的实现RR的不同概念:MySQL repeatable read and lost update/phantom reads
您可以推断在您在本测试中使用的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 Levels在the 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)以任何顺序)