2012-01-30 188 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)以任何順序)