hiernate的鎖機制

2021-04-12 20:38:36 字數 2602 閱讀 2938

hibernate鎖機制包括悲觀鎖和樂觀鎖

1.悲觀鎖:

它指的是對資料被外界修改持保守態度。假定任何時刻訪問資料時,都可能有另乙個客戶也正在

訪問同一筆資料,為了保持資料被操作的一致性,於是對資料採取了資料庫層次的鎖定狀態,依靠數

據庫提供的鎖機制來實現。

基於jdbc實現的資料庫加鎖如下:

select * from account where name="erica" for update.在更新的過程中,資料庫處於加鎖狀

態,任何其他的針對本條資料的操作都將被延遲。本次事務提交後解鎖。

而hibernate悲觀鎖的具體實現如下:

string sql="查詢語句";

query query=session.createquery(sql);

query.setlockmode("物件",lockmodel.upgrade);

說到這裡,就提到了hiernate的加鎖模式:

lockmode.none : 無鎖機制。

lockmode.write :hibernate在insert和update記錄的時候會自動獲取。

lockmode.read : hibernate在讀取記錄的時候會自動獲取。

這三種加鎖模式是供hibernate內部使用的,與資料庫加鎖無關

lockmode.upgrade:利用資料庫的for update字句加鎖。

在這裡我們要注意的是:只有在查詢開始之前(也就是hiernate生成sql語句之前)加鎖,才會真

正通過資料庫的鎖機制加鎖處理。否則,資料已經通過不包含for updata子句的sql語句載入進來,

所謂的資料庫加鎖也就無從談起。

但是,從系統的效能上來考慮,對於單機或小系統而言,這並不成問題,然而如果是在網路上的

系統,同時間會有許多聯機,假設有數以百計或上千甚至更多的併發訪問出現,我們該怎麼辦?如果

等到資料庫解鎖我們再進行下面的操作,我們浪費的資源是多少?--這也就導致了樂觀鎖的產生。

2.樂觀鎖:

樂觀鎖定(optimistic locking)則樂觀的認為資料的訪問很少發生同時訪問的問題,因而不作數

據庫層次上的鎖定,為了維護正確的資料,樂觀鎖定採用應用程式上的邏輯實現版本控制的方法。

例如若有兩個客戶端,a客戶先讀取了賬戶餘額100元,之後b客戶也讀取了賬戶餘額100元的資料,

a客戶提取了50元,對資料庫作了變更,此時資料庫中的餘額為50元,b客戶也要提取30元,根據其所

取得的資料,100-30將為70餘額,若此時再對資料庫進行變更,最後的餘額就會不正確。

在不實行悲觀鎖定策略的情況下,資料不一致的情況一但發生,有幾個解決的方法,一種是先更新

為主,一種是後更新的為主,比較複雜的就是檢查發生變動的資料來實現,或是檢查所有屬性來實現

樂觀鎖定。

hibernate 中透過版本號檢查來實現後更新為主,這也是hibernate所推薦的方式,在資料庫中加

入乙個verson欄記錄,在讀取資料時連同版本號一同讀取,並在更新資料時遞增版本號,然後比對版

本號與資料庫中的版本號,如果大於資料庫中的版本號則予以更新,否則就回報錯誤。

以剛才的例子,a客戶讀取賬戶餘額1000元,並連帶讀取版本號為5的話,b客戶此時也讀取賬號餘

額1000元,版本號也為5,a客戶在領款後賬戶餘額為500,此時將版本號加1,版本號目前為6,而數

據庫中版本號為5,所以予以更新,更新資料庫後,資料庫此時餘額為500,版本號為6,b客戶領款後

要變更資料庫,其版本號為5,但是資料庫的版本號為6,此時不予更新,b客戶資料重新讀取資料庫

中新的資料並重新進行業務流程才變更資料庫。

以hibernate實現版本號控制鎖定的話,我們的物件中增加乙個version屬性,例如:

public class account 

public int getversion() 

....

}而在映像檔案中,我們使用optimistic-lock屬性設定version控制,屬性欄之後增加乙個

標籤,如下:

optimistic-lock="version">

....

設定好版本控制之後,在上例中如果b 客戶試圖更新資料,將會引發stableobjectstateexception

例外,我們可以捕捉這個例外,在處理中重新讀取資料庫中的資料,同時將 b客戶目前的資料與資料

庫中的資料秀出來,讓b客戶有機會比對不一致的資料,以決定要變更的部份,或者您可以設計程式

自動讀取新的資料,並重複扣款業務流程,直到資料可以更新為止,這一切可以在背景執行,而不用

讓您的客戶知道。

但是樂觀鎖也有不能解決的問題存在:上面已經提到過樂觀鎖機制的實現往往基於系統中的資料

儲存邏輯,在我們的系統中實現,來自外部系統的使用者餘額更新不受我們系統的控制,有可能造成非

法資料被更新至資料庫。因此我們在做電子商務的時候,一定要小心的注意這項存在的問題,採用比

較合理的邏輯驗證,避免資料執行錯誤。

也可以在使用session的load()或是lock()時指定鎖定模式以進行鎖定。

如果資料庫不支援所指定的鎖定模式,hibernate會選擇乙個合適的鎖定替換,而不是丟出乙個例

外 

python鎖機制 python的鎖機制

鎖 lock lock 指令鎖 是可用的最低階的同步指令。lock處於鎖定狀態時,不被特定的執行緒擁有。lock包含兩種狀態 鎖定和非鎖定,以及兩個基本的方法。可以認為lock有乙個鎖定池,當執行緒請求鎖定時,將執行緒至於池中,直到獲得鎖定後出池。池中的執行緒處於狀態圖中的同步阻塞狀態。構造方法 l...

python鎖機制 python 鎖機制

當有兩個或跟多個執行緒或程序需要操作乙個變數或程序時,會出現意想不到的結果,這是因為執行緒或程序時迸發進行的,對同意變數或檔案操作時,會出現同時對其操作,從到導致邏輯錯誤。bin usr env python coding utf 8 import multiprocessing import ti...

mysql鎖機制 php Mysql鎖機制

表級鎖 開銷小,加鎖快 不會出現死鎖 鎖定粒度大,發生鎖衝突的概率最高,併發度最低。行級鎖 開銷大,加鎖慢 會出現死鎖 鎖定粒度最小,發生鎖衝突的概率最低,併發度也最高。共享鎖和排它鎖 頁面鎖 開銷和加鎖時間界於表鎖和行鎖之間 會出現死鎖 鎖定粒度界於表鎖和行鎖之間,併發度一般 mysql的行級鎖有...