使用可重複讀取隔離級別,仍有可能丟失更新(第二次丟失更新問題)。例如。在與隔離級別的場景設置爲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)以任何順序)