025 hibernate悲觀鎖 樂觀鎖

2021-09-06 19:25:06 字數 3855 閱讀 3993

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

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

資料庫隔離級別:見前面章級

悲觀鎖:具有排他性(我鎖住當前資料後,別人看到不此資料)

悲觀鎖一般由資料機制來做到的。

通常依賴於資料庫機制,在整修過程中將資料鎖定,其它任何使用者都不能讀取或修改(如:必需我修改完之後,別人才可以修改)

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

長事務占有時間(如果占有1個小時,那麼這個1小時別人就不可以使用這些資料),不常用。

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

hibernate使用load進行悲觀鎖載入。

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

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

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();

執行輸出sql語句:hibernate: select inventory0_.itemno as itemno0_0_, inventory0_.itemname as itemname0_0_, inventory0_.quantity as quantity0_0_ from t_inventory inventory0_ where inventory0_.itemno=? for update //在select語句中加入for update進行使用悲觀鎖。

腦白金hibernate: update t_inventory set itemname=?, quantity=? where itemno=?

注:只有使用者釋放鎖後,別的使用者才可以讀取

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

select…for update語句的語法與select語句相同,只是在select語句的後面加for update [nowait]子句。

該語句用來鎖定特定的行(如果有where子句,就是滿足where條件的那些行)。當這些行被鎖定後,其他會話可以選擇這些行,但不能更改或刪除這些行,直到該語句的事務被commit語句或rollback語句結束為止。 

樂觀鎖:不是鎖,是一種衝突檢測機制。

樂觀鎖的併發性較好,因為我改的時候,別人隨邊修改。

樂觀鎖的實現方式:常用的是版本的方式(每個資料表中有乙個版本欄位version,某乙個使用者更新資料後,版本號+1,另乙個使用者修改後再+1,當使用者更新發現資料庫當前版本號與讀取資料時版本號不一致(等於小於資料庫當前版本號),則更新不了。

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

public

class

inventory

public

void setitemno(int

itemno)

public

string getitemname()

public

void

setitemname(string itemname)

public

intgetquantity()

public

void setquantity(int

quantity)

public

intgetversion()

public

void setversion(int

version)

}

<

>

<

class

name

="com.wjt276.hibernate.inventory"

table

="t_inventory"

optimistic-lock

="version"

>

<

id name

="itemno"

>

<

generator

class

="native"

/>

id>

<

version

name

="version"

/>

—必需配置在主鍵對映後面 --

>

<

property

name

="itemname"

/>

<

property

name

="quantity"

/>

class

>

>

匯出輸出sql語句:create table t_inventory (itemno integer not null auto_increment, version integer not null, itemname varchar(255), quantity integer, primary key (itemno))

注:新增的版本字段version,還是我們來維護的,是由hibernate來維護的。

樂觀鎖在儲存資料時不用關心。

要注意的是,由於樂觀鎖定是使用系統中的程式來控制,而不是使用資料庫中的鎖定機制,因而如果有人特意自行更新版本訊息來越過檢查,則鎖定機制就會無效,例如在上例中自行更改stu的version屬性,使之與資料庫中的版本號相同的話就不會有錯誤,像這樣版本號被更改,或是由於資料是由外部系統而來,因而版本資訊不受控制時,鎖定機制將會有問題,設計時必須注意。

hibernate悲觀鎖 樂觀鎖

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

hibernate悲觀鎖和樂觀鎖

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

hibernate樂觀鎖和悲觀鎖

談到悲觀鎖和樂觀鎖,就要談到資料庫的併發問題,資料庫的隔離級別越高併發性就越差 併發性 當前系統進行了序列化後,你讀取資料庫後,別人查詢不了,稱為併發性不好 具有排它性 我鎖住當前資料後,比人看不到此資料 悲觀鎖一般是由資料庫機制來做到的 悲觀鎖的實現 通常依賴於資料庫機制,在整修過程中將資料庫鎖定...