hibernate樂觀鎖和悲觀鎖

2021-07-26 16:15:40 字數 3166 閱讀 7129

談到悲觀鎖和樂觀鎖,就要談到資料庫的併發問題,資料庫的隔離級別越高併發性就越差

併發性:

當前系統進行了序列化後,你讀取資料庫後,別人查詢不了,稱為併發性不好

具有排它性(我鎖住當前資料後,比人看不到此資料),悲觀鎖一般是由資料庫機制來做到的

悲觀鎖的實現:

通常依賴於資料庫機制,在整修過程中將資料庫鎖定,其它任何使用者都不能讀取或修改

悲觀鎖的適用場景:

悲觀鎖一般適合短事物比較多(如某乙個資料取出後加1,立即釋放)

例項:

使用者1,使用者2同時讀取到資料,但是使用者2先-200,這時資料庫裡的是800,現在使用者1也開始-200,可以使用者1剛才讀取到的資料是1000,現在使用者用剛一開始讀取的資料1000-200,而使用者1在更新時資料庫裡的資料是800,按理說使用者1應該是800-200=600,這樣就造成更新丟失。這種情況下可採用兩種方式解決:悲觀鎖、樂觀鎖。

悲觀鎖:使用者1讀取資料後,用鎖將其讀取的資料鎖上,這時使用者2是讀取不到資料的,只有使用者1釋放鎖後使用者2才可以讀取,同樣使用者2讀取資料的資料也鎖上,這樣就可以解決更新丟失了。

實體類:

[html]view plain

copy

public class inventory   

public void setitemno(int itemno)   

public string getitemname()   

public void setitemname(string itemname)   

public int getquantity()   

public void setquantity(int quantity)      

}  

對映檔案:

[html]view plain

copy

<

>

<

class

name

="com.cn.hibernate.inventory"

table

="t_inventory"

>

<

idname

="itemno"

>

<

generator

class

="native"

/>

id>

<

property

name

="itemname"

/>

<

property

name

="quantity"

/>

class

>

>

悲觀鎖的使用:

如果要使用悲觀鎖,肯定在載入資料時就要鎖住,通常採用for update語句

hibernate使用load進行悲觀鎖載入

session.load(class arg(),serializable arg1,lockmode arg2)throws hibernateexception

lockmode:悲觀鎖模式(一般使用lockmode.upgrade)

[html]view plain

copy

session

= hibernateutils

.getsession();  

tx= 

session

.begintransaction();  

inventory inv

= (inventory)session.load(inventory.class, 1, lockmode.upgrade);  

system.out.println(inv.getitemname());  

inv.setquantity(inv.getquantity()-200);  

session.update(inv);  

tx.commit();  

如果使用悲觀鎖,那麼lazy(懶載入)無效

樂觀鎖:不是鎖,是一種衝突檢測機制,樂觀鎖的併發性較好,因為我改的時候,別人可隨便修改樂觀鎖的實現方式:常用的是版本的方式(每個資料表中有乙個版本欄位version,某乙個使用者更新資料庫後,版本號+1,另乙個使用者修改後再+1,當使用者更新發現資料庫當前版本號與讀取資料時版本號不一致,等於或小於資料庫版本號則更新不了)

hibernate使用樂觀鎖需要在對映檔案中配置才可生效

實體類

[html]view plain

copy

<

prename

="code"

class

="html"

>

public class inventory   

public void setitemno(int itemno)   

public string getitemname()   

public void setitemname(string itemname)   

public int getquantity()   

public void setquantity(int quantity)   

public int getversion()   

public void setversion(int version)   

}  pre

>

<

pre>

pre>

<

p>

p>

<

pre>

pre>

<

pre>

pre>

<

pre>

pre>

<

pre>

pre>

原文出自:

hibernate悲觀鎖 樂觀鎖

1.多個事務併發會出現的錯誤情況 1 dirty read髒讀 讀了其他事務沒有提交的資料 2 none repeatable read不可重複讀 在同乙個事務中讀兩次得到不同的結果 3 phantom read幻讀 在同乙個事務中讀兩次得到不同的結果 針對插入和刪除 為了解決事務併發出現的三個問題...

hibernate悲觀鎖和樂觀鎖

如果資料庫不加鎖,在多個使用者訪問的時候,有可能會造成不可重複讀的問題 如,兩個使用者進行更新,並且這兩個使用者都先後的拿到了表中的記錄的數值,a使用者更新比 b使用者先更新完,但 b使用者還是按照初始的值進行更新,這時候就會造成不可重複讀 此時可以通過hibernate的悲觀鎖機制,對 hiber...

hibernate悲觀鎖和樂觀鎖

1.悲觀鎖 它指的是對資料被外界修改持保守態度。假定任何時刻訪問資料時,都可能有另乙個客戶也正在訪問同一筆資料,為了保持資料被操作的一致性,於是對資料採取了資料庫層次的鎖定狀態,依靠資料庫提供的鎖機制來實現。基於jdbc實現的資料庫加鎖如下 select from account where nam...