hibernate支持兩種鎖:悲觀鎖(Pessimistic Locking)和樂觀鎖(Optimistic Locking) 悲觀鎖:指的是對數據庫數據被外界的修改持保守態(tài)度(無論是本系統(tǒng)的事務處理,或者是外部系統(tǒng)的事務處理),在整個數據處理的過程數據都處于鎖定的狀態(tài)。hibernate中的
hibernate支持兩種鎖:悲觀鎖(Pessimistic Locking)和樂觀鎖(Optimistic Locking)
悲觀鎖:指的是對數據庫數據被外界的修改持保守態(tài)度(無論是本系統(tǒng)的事務處理,或者是外部系統(tǒng)的事務處理),在整個數據處理的過程數據都處于鎖定的狀態(tài)。hibernate中的悲觀鎖,是依靠數據庫中的鎖機制(因為只有數據庫層才能控制本系統(tǒng)和外部系統(tǒng)對數據庫的數據操作)。
例如”select * from user where userName=’Johnson’ for update“這條sql鎖定了user表中所有userName=’Johnson’的記錄,本次事務提交之前,外界無法修改這些記錄。
hibernate中的悲觀鎖,也是基于數據庫的鎖機制實現的。
String hqlStr ="from TUser as user where user.name='Lili'";
Query query = session.createQuery(hqlStr);
query.setLockMode("user",LockMode.UPGRADE); //加鎖
List userList = query.list();//執(zhí)行查詢,獲取數據
上面的代碼中setLockMode第一個參數指定了別名為user的返回的記錄進行上鎖。
生成的sql為:
select tuser0_.id as id, tuser0_.name as name, tuser0_.group_id
as group_id, tuser0_.user_type as user_type, tuser0_.sex as sex
from t_user tuser0_ where (tuser0_.name='Erica' ) for update
可見hibernate通過數據庫中的for update子句實現悲觀鎖機制。
hibernate的加鎖模式:
LockMode.NONE : 無鎖機制。
LockMode.WRITE : Hibernate 在 Insert 和 Update 記錄的時候會自動獲取。
LockMode.READ : Hibernate 在讀取記錄的時候會自動獲取。
以上這三種鎖機制一般由 Hibernate 內部使用,如 Hibernate 為了保證 Update過程中對象不會被外界修改,會在 save 方法實現中自動為目標對象加上 WRITE 鎖。
LockMode.UPGRADE :利用數據庫的 for update 子句加鎖。
LockMode. UPGRADE_NOWAIT : Oracle 的特定實現,利用 Oracle 的 for update nowait 子句實現加鎖。
上面這兩種鎖機制是我們在應用層較為常用的,加鎖一般通過以下方法實現:
Criteria.setLockMode
Query.setLockMode
Session.lock
相對于悲觀鎖,樂觀鎖的鎖機制就顯得比較寬松。悲觀鎖大部分情況依靠數據庫的鎖機制實現,來保證最大程度的獨占性。但另一方面數據庫的開銷非常大,尤其對于長事務來說。
樂觀鎖大部分是基于數據版本(version)記錄機制實現。即在數據表中增加一個版本標識,讀取出數據時,連帶這個版本標識一起讀出,更新數據的時候,把版本標識加1。將提交版本數據跟數據庫中當前版本信息對比,如果提交的數據中版本號大于數據表當前的版本號,則允許更新,否則認為是過期數據。
hibernate的樂觀鎖主要有兩種方式:version和時間戳
舉個配置的例子:
樂觀鎖帶來的負面問題:如果兩個不同的事務同時讀取一條數據并進行更新時,程序會報異常:org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect)。這時候就要捕獲異常,然后處理并提醒用戶再次提交。
同樣,樂觀鎖也有局限性。就是只控制了本系統(tǒng)的事務并發(fā)操作,而外部系統(tǒng)對數據表的操作卻無法控制,此時有個解決辦法就是:在存儲過程里實現樂觀鎖機制,這樣無論是本系統(tǒng)或是外部系統(tǒng)的事務操作,數據庫都可以控制。所以,在設計階段,盡量考慮到各種情況,究竟是在程序端實現好,還是數據庫端實現比較好。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com