0

當試圖瞭解基於版本的樂觀鎖定如何防止「最後提交贏」問題和適當的覆蓋時,我遇到了困難。樂觀鎖定和覆蓋

爲了使問題更具體,讓我們考慮使用以下僞代碼JDBC:

connection.setAutoCommit(false); 
Account account = select(id); 
if (account.getBalance() >= amount) { 
    account.setBalance(account.getBalance() - amount); 
} 
int rowsUpdated = update(account); // version=:oldVer+1 WHERE version=:oldVer 
if (rowsUpdated == 0) throw new OptimisticLockException(); 
connection.commit(); 

這裏什麼,如果其他交易將提交更新和承諾之間權利的變化?如果事務是併發的,那麼第一個事務所做的更新尚未提交,因此對於第二個事務(具有適當的隔離級別)不可見,因此第一個事務提交將在沒有任何通知的情況下覆蓋第二個事務的更改或錯誤。

這是樂觀鎖只是減少問題的概率,而不是通常阻止它的情況?

回答

0

數據庫「事務」的想法是它應該提供跨多個概念操作的「一致性」保證。數據庫負責執行此操作。所以,當事務提交時,數據庫應該只允許事務完成,如果它可以確保事務中發生的所有事情仍然有效。

實際上,數據庫通常會處理這種情況,一旦某個更新成功完成,相關行將被鎖定,直到相關事務完成。因此,其中一個更新被保證失敗。

注意:這也需要在jdbc連接中有適當的隔離級別。隔離級別確保在寫入時更新之前完成的當前值的測試仍然適用。

+0

因此,丟失的事務只會在「更新」方法中被阻塞,並等待獲勝提交,對嗎? – AngryJuice

+0

@AngryJuice - 它可能取決於你的數據庫如何處理隔離級別,但是,這是最可能的情況。 – jtahlborn

+0

謝謝,這就是我最初的建議 – AngryJuice