在使用hibernate的過程我們會遇到多個人對同一資料同時進行修改,這個時候就會發生髒資料,造成資料的不一致性。為了避免更新資料的丟失,hibernate
採用鎖機制。
hibernate提供了兩種鎖機制:悲觀鎖和樂觀鎖。
悲觀鎖:在資料有載入的時候就給其進行加鎖,直到該鎖被釋放掉,其他使用者才可以進行修改。
樂觀鎖:在對資料進行修改的時候,對資料採用版本號或者時間戳等方式來比較,資料是否一致性來實現加鎖。
一、悲觀鎖
悲觀鎖是依靠資料庫提供的鎖機制。hibernate
是通過使用資料庫的for update
子句實現了悲觀鎖機制。
hibernate有如下五種加鎖機制
1、 lockmode.none:無鎖機制
2、lockmode.write:
hibernate
在insert
和update
記錄的時候會自動獲取
3、lockmode.read:
hibernate
在讀取記錄的時候會自動獲取
4、lockmode.upgrade:利用資料庫的
for update
子句加鎖
5、lockmode.upgrade_nowait:
oracle
的特定實現,利用
oracle
的for update nowait
子句實現加鎖
悲觀加鎖一般通過以下三種方法實現:
1、criteria.setlockmode
2、query.setlockmode
3、session.lock
下面示例是對查詢進行加鎖:
public void query(int id)產生的sql語句如下:}
select users0_.id as id0_, users0_.ver as ver0_,悲觀鎖在對資料進行加鎖後,會一直「霸佔」該資料,直到釋放掉,其他使用者才可以對該資料進行更新。這裡就存在乙個問題,如果它一直佔著不放,那麼其他使用者永遠也不可能對該資料進行更新,這樣就很不利於併發了。對於這個問題的解決方案,可以利用樂觀鎖。users0_.birthday as birthday0_, users0_.first_name as first4_0_, users0_.last_name as last5_0_ from users users0_
with (updlock, rowlock) where users0_.id=?
二、樂觀鎖
樂觀鎖大多是基於資料版本記錄機制實現。何謂資料版本?即為資料增加乙個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加乙個「version」
欄位來實現。讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。
我們可以通過class
描述符的
optimistic-lock
屬性結合
version
描述符指定樂觀鎖。
1. none:無樂觀鎖
2. version:通過版本機制實現樂觀鎖
3. dirty:通過檢查發生變動過的屬性實現樂觀鎖
4. all:通過檢查所有屬性實現樂觀鎖
在實現樂觀鎖的持久化類我們需要為該持久化類增加乙個version屬性,並且提供相應的
getter
和setter
方法。如下
public class users配置檔案:
注意:version 節點必須出現在
id 節點之後。
在這裡我們宣告了乙個version屬性,該屬性用於存放使用者的版本資訊。我們對
user
表每一次更新操作,都會引起
version
屬性的變化:加
1。如果我們嘗試在tx.commit
之前,啟動另外乙個
session
,對名為同乙個使用者進行操作,就是併發更新的情形了:
public void update()執行以上**,**將在
.....2
處丟擲staleobjectstateexception
異 常,並指出版本檢查失敗
。在這裡是先提交者成功,後提交者失敗。
當前事務正在試圖提交乙個過期資料。通過捕捉這個異常,
我們就可以在樂觀鎖校驗失敗時進行相應處理
。
Hibernate讀書筆記 樂觀鎖與悲觀鎖
在使用hibernate的過程我們會遇到多個人對同一資料同時進行修改,這個時候就會發生髒資料,造成資料的不一致性。為了避免更新資料的丟失,hibernate 採用鎖機制。hibernate提供了兩種鎖機制 悲觀鎖和樂觀鎖。悲觀鎖 在資料有載入的時候就給其進行加鎖,直到該鎖被釋放掉,其他使用者才可以進...
Hibernate讀書筆記 資料過濾
hibernate3 提供了一種創新的方式來處理具有 顯性 visibility 規則的資料,那就是使用hibernate filter。hibernate filter是全域性有效的 具有名字 可以帶引數的過濾器,對於某個特定的hibernate session 您可以選擇是否啟用 或禁用 某個過...
mysql運維 讀書筆記 Mysql 讀書筆記
mysql儲存時間有兩種型別 datetime和timestamp。分別說一下兩者的區別。datetime,以8位元組儲存時間,理論上可以從0000年儲存到9999年。並且沒有時區的概念,它儲存的就是乙個時間點的概念。timestamp和datetime最主要的不同就是,它是以4個位元組儲存,由19...