2013-06-03 95 views
4

使用樂觀鎖定策略時,它可以解決像下面併發問題:樂觀鎖定絕對安全嗎?

 
| the first transaction started  | 
|          | 
| select a row       | 
|          | the second transaction started 
| update the row with version checking | 
|          | select the same row 
| commit txn       | 
|          | update the row with version checking 
|          | 
|          | rolls back because version is dirty 

但是,如果在極少數情況下,如果在第二個事務更新是在第一筆交易,但之前的UDPATE後交易提交?

 
| the first transaction started  | 
|          | the second transaction started 
| select a row       | 
|          | select the same row 
| update the row with version checking | 
|          | update the row with version checking 
| commit txn       | 
|          | rolls back because version is dirty // will it? 
|          | 
|          | 

我做了一個實驗,在第二個事務更新無法讀取「髒」的版本,因爲第一個事務還沒有被提交。第二筆交易在這種情況下會失敗嗎?

+0

@亞當阿羅德謝謝你告訴我這句格言。我谷歌因爲我不是一個本地的英語演講者:)但樂觀鎖定策略會在我提到的情況下工作嗎? – Hippoom

+0

如果真的樂觀,你怎麼使用交易功能?更新將自動失敗,無需任何回滾。 – tia

+0

@tia也許在這個例子中,無論有無事務都可以。但有時我需要將其他更改(例如可能插入某個子表的某些子元素)回滾到數據庫 – Hippoom

回答

2

你沒有在你的問題中說你實際使用的數據庫系統,所以我不知道你係統的細節。

但是在任何情況下,在樂觀鎖定系統下,進程不能只在執行更新語句時檢查行版本,因爲您確實擔心您擔心的問題。

對於完全可序列化的隔離事務,每個進程必須在提交時自動檢查所檢查和修改的所有行的行版本。因此,在第二種情況下,右側流程在嘗試提交之前不會檢測到衝突(您未包含在右側流程中的步驟)。當它嘗試提交時,它會檢測到衝突並回滾。

+0

感謝您的回覆。我們在生產環境中使用Oracle 10g,隔離級別被讀取提交。 – Hippoom

+0

它會在嘗試提交時真的失敗。我的意思是,當數字檢查在使用樂觀鎖定時失敗時,它不會拋出異常,它只是更新0行,而當受影響的行等於0時,開發人員會拋出異常。 – Hippoom

+0

也許我可以做另一個實驗,在更新sql被執行,但在提交事務之前更新另一個線程中的同一行,然後喚醒第一個線程。 – Hippoom