悲觀鎖和樂觀鎖

2022-09-12 19:51:16 字數 1596 閱讀 5822

我們通常希望避免在兩個並行事務中產生如下情形:

adam的事務讀取資料 x

barbara的事務讀取資料 x

adam的事務修改資料 x,並將其修改為 xa

adam的事務寫入資料 xa

barbara的事務修改資料 x,並將其修改為 xb

barbara的事務寫入資料 xb

結果是,adam所做的修改完全被barbara所覆蓋掉了,但是barbara對此卻毫不知曉。像這樣的情況通常被稱為「髒讀」。顯然,我們希望的結果是adam寫入 xa,而barbara需要在寫入 xb之前檢查對 xa 的修改。

樂觀鎖的工作原理 (optimistic locking )

樂觀鎖基於的假設是實際中衝突很少發生,即使發生,丟擲乙個錯誤也比想辦法避免它們更容易接受和簡單。在樂觀鎖中,允許乙個事務正確完成,但另乙個事務需要丟擲異常並回滾,並且必須被重新執行或者丟棄。

我們還以adam和barbara為例,下面是乙個使用樂觀鎖可能發生的情形:

adam的事務讀取資料 x

barbara的事務讀取資料 x

adam的事務修改資料 x,並將其修改為 xa

adam的事務寫入資料 xa

barbara的事務修改資料 x,並將其修改為 xb

barbara的事務試圖寫入資料 xb,但是收到乙個錯誤

barbara需要讀取資料 xa(或者重新開始乙個新的事務)

barbara的事務修改資料 xa,並將其修改為 xab

barbara的事務寫入資料 xab

如你所見,barbara被強制要求檢查adam的修改,並且她可以選擇繼續修改adam的結果並儲存(合併修改)。最後的資料將同時包括adam和barbara的修改。

樂觀鎖完全由jpa控制。它需要在db表中額外儲存乙個版本號列。它完全依靠於底層用來儲存關係型資料的db引擎來工作。

悲觀鎖的工作原理(pessimistic lock)

對於某些人來說,悲觀鎖更容易接受。當事務需要修改乙個可能被其他事務同時修改的實體時,事務會發起乙個命令將實體鎖住。所有的鎖會持續到事務結束後再自動釋放。

使用悲觀鎖的情形可能如下所示:

adam的事務讀取資料 x

adam的事務鎖住 x

barbara的事務希望讀取資料 x,但是因為 x 已經被鎖住,只好等待

adam的事務修改資料 x,並將其修改為 xa

adam的事務寫入資料 xa

barbara的事務讀取資料 xa

barbara的事務修改資料 xa,並將其修改為 xab

barbara的事務寫入資料 xab

如你所見,barbara又一次被強制的寫入 xab,同時也包含了adam的修改。但是,這個方案與樂觀鎖完全不同——barbara需要等待adam的事務完成以後才能夠讀取資料。更甚的是,為了讓該場景正確工作,我們需要在兩個事務中都手動發起乙個lock命令。(因為我們並不確定那個事務先執行,所以兩個事務都需要在修改資料前先進行鎖定)雖然樂觀鎖要為每個實體增加乙個版本列,比悲觀鎖工作略多,但是之後我們不需要再在事務中發起鎖操作了。jpa會自動完成所有的檢查,我們只需要處理可能的異常即可。

悲觀鎖使用底層資料庫提供的鎖機制來鎖住表中已有的記錄。jpa需要知道如何觸發這些鎖,並且尚不能完全支援某些資料庫。

悲觀鎖和樂觀鎖

1.悲觀鎖,正如其名,它指的是對資料被外界 包括本系統當前的其他事務,以及來自外部系統的事務處理 修改持保守態度,因此,在整個資料處理過程中,將資料處於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制 也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無...

悲觀鎖和樂觀鎖

前幾天有人問了我乙個問題,說如果資料庫某些操作不用事務,那麼又需要保持資料的一致性,那麼該用什麼方法替代事務。我就想到了悲觀鎖和樂觀鎖的思想,下面我解釋一下在資料庫中的悲觀鎖和樂觀鎖 1.悲觀鎖就是把資料庫的一些操作,放在事務當中,依賴資料庫的隔離級別,實現對資料修改的封鎖,這樣做資料一致性可以保持...

悲觀鎖和樂觀鎖

悲觀鎖 pessimistic lock 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖。樂觀鎖 optim...