成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Hibernate事務與并發問題處理

開發 后端
數據庫事務,是指作為單個邏輯工作單元執行的一系列操作。事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會永久更新面向數據的資源。下文將講解一些并發問題的處理。

一、數據庫事務的定義

數據庫事務(Database Transaction) ,是指作為單個邏輯工作單元執行的一系列操作。事務處理可以確保除非事務性單元內的所有操作都成功完成,否則不會***更新面向數據的資源。通過將一組相關操作組合為一個要么全部成功要么全部失敗的單元,可以簡化錯誤恢復并使應用程序更加可靠。一個邏輯工作單元要成為事務,必須滿足所謂的ACID(原子性、一致性、隔離性和持久性)屬性。 

  1. 原子性(atomic),事務必須是原子工作單元;對于其數據修改,要么全都執行,要么全都不執行

  2. 一致性(consistent),事務在完成時,必須使所有的數據都保持一致狀態。

  3. 隔離性(insulation),由并發事務所作的修改必須與任何其它并發事務所作的修改隔離。

  4. 持久性(Duration),事務完成之后,它對于系統的影響是***性的。

二、數據庫事務并發可能帶來的問題 

如果沒有鎖定且多個用戶同時訪問一個數據庫,則當他們的事務同時使用相同的數據時可能會發生問題。由于并發操作帶來的數據不一致性包括:丟失數據修改、讀”臟”數據(臟讀)、不可重復讀、產生幽靈數據:

假設數據庫中有如下一張表:

1. ***類丟失更新(lost update): 在完全未隔離事務的情況下,兩個事物更新同一條數據資源,某一事物異常終止,回滾造成***個完成的更新也同時丟失。

在T1時刻開啟了事務1,T2時刻開啟了事務2,在T3時刻事務1從數據庫中取出了 id="402881e535194b8f0135194b91310001"的數據,T4時刻事務2取出了同一條數據,T5時刻事務1將age字段值更新為30,T6時刻事務2更新age為35并提交了數據,但是T7事務1回滾了事務age***的值依然為20,事務2的更新丟失了,這種情況就叫做"***類丟失更新(lost update)"。

2. 臟讀(dirty read):如果第二個事務查詢到***個事務還未提交的更新數據,形成臟讀。

在T1時刻開啟了事務1,T2時刻開啟了事務2,在T3時刻事務1從數據庫中取出了id="402881e535194b8f0135194b91310001"的數據,在T5時刻事務1將age的值更新為30,但是事務還未提交,T6時刻事務2讀取同一條記錄,獲得age的值為30,但是事務1還未提交,若在T7時刻事務1回滾了事務2的數據就是錯誤的數據(臟數據),這種情況叫做" 臟讀(dirty read)"。

3. 虛讀(phantom read):一個事務執行兩次查詢,第二次結果集包含***次中沒有或者某些行已被刪除,造成兩次結果不一致,只是另一個事務在這兩次查詢中間插入或者刪除了數據造成的。

在T1時刻開啟了事務1,T2時刻開啟了事務2,T3時刻事務1從數據庫中查詢所有記錄,記錄總共有一條,T4時刻事務2向數據庫中插入一條記錄,T6時刻事務2提交事務。T7事務1再次查詢數據數據時,記錄變成兩條了。這種情況是"虛讀(phantom read)"。

4. 不可重復讀(unrepeated read):一個事務兩次讀取同一行數據,結果得到不同狀態結果,如中間正好另一個事務更新了該數據,兩次結果相異,不可信任。

在T1時刻開啟了事務1,T2時刻開啟了事務2,在T3時刻事務1從數據庫中取出了 id="402881e535194b8f0135194b91310001"的數據,此時age=20,T4時刻事務2查詢同一條數據,T5事務2更新數據age=30,T6時刻事務2提交事務,T7事務1查詢同一條數據,發現數據與***次不一致。這種情況就是"不可重復讀(unrepeated read)"。

5. 第二類丟失更新(second lost updates):是不可重復讀的特殊情況,如果兩個事務都讀取同一行,然后兩個都進行寫操作,并提交,***個事務所做的改變就會丟失。

在T1時刻開啟了事務1,T2時刻開啟了事務2,T3時刻事務1更新數據age=25,T5時刻事務2更新數據age=30,T6時刻提交事務,T7時刻事務2提交事務,把事務1的更新覆蓋了。這種情況就是"第二類丟失更新(second lost updates)"。

三、數據庫事務隔離級別

為了解決數據庫事務并發運行時的各種問題數據庫系統提供四種事務隔離級別:

1. Serializable 串行化

2. Repeatable Read 可重復讀

3. Read Commited 可讀已提交

4. Read Uncommited 可讀未提交

隔離級別與并發性能的關系: 

每一個隔離級別可以解決的問題:


 

四、使用Hibernate設置數據庫隔離級別

在Hibernate的配置文件中可以顯示的配置數據庫事務隔離級別。每一個隔離級別用一個整數表示:

8 - Serializable 串行化

4 - Repeatable Read 可重復讀

2 - Read Commited 可讀已提交

1 - Read Uncommited 可讀未提交

在hibernate.cfg.xml中使用hibernate.connection.isolation參數配置數據庫事務隔離級別。

五、使用悲觀鎖解決事務并發問題

悲觀鎖,正如其名,它指的是對數據被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個數據處理過程中,將數據處于鎖定狀態。悲觀鎖的實現,往往依靠數據庫提供的鎖機制(也只有數據庫層提供的鎖機制才能真正保證數據訪問的排他性,否則,即使在本系統中實現了加鎖機制,也無法保證外部系統不會修改數據)。

一個典型的依賴數據庫的悲觀鎖調用:select * from account where name=”Erica” for update這條 sql 語句鎖定了 account 表中所有符合檢索條件( name=”Erica” )的記錄。本次事務提交之前(事務提交時會釋放事務過程中的鎖),外界無法修改這些記錄。悲觀鎖,也是基于數據庫的鎖機制實現。

在Hibernate使用悲觀鎖十分容易,但實際應用中悲觀鎖是很少被使用的,因為它大大限制了并發性:

圖為Hibernate3.6的幫助文檔Session文檔的get方法截圖,可以看到get方法第三個參數"lockMode" 或"lockOptions",注意在Hibernate3.6以上的版本中"LockMode"已經不建議使用。方法的第三個參數就是用來設置悲觀鎖的,使用第三個參數之后,我們每次發送的SQL語句都會加上"for update"用于告訴數據庫鎖定相關數據。

LockMode參數選擇該選項,就會開啟悲觀鎖。

T1,T2時刻取款事務和轉賬事務分別開啟,T3事務查詢ACCOUNTS表的數據并用悲觀鎖鎖定,T4轉賬事務也要查詢同一條數據,數據庫發現該記錄已經被前一個事務使用悲觀鎖鎖定了,然后讓轉賬事務等待直到取款事務提交。T6時刻取款事務提交,T7時刻轉賬事務獲取數據。

六、使用樂觀鎖解決事務并發問題

相對悲觀鎖而言,樂觀鎖機制采取了更加寬松的加鎖機制。悲觀鎖大多數情況下依靠數據庫的鎖機制實現,以保證操作***程度的獨占性。但隨之而來的就是數據庫性能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基于數據版本(Version)記錄機制實現。何謂數據版本?即為數據增加一個版本標識,在基于數據庫表的版本解決方案中,一般是通過為數據庫表增加一個"version"字段來實現。

樂觀鎖的工作原理:讀取出數據時,將此版本號一同讀出,之后更新時,對此版本號加一。此時,將提交數據的版本數據與數據庫表對應記錄的當前版本信息進行比對,如果提交的數據版本號大于數據庫表當前版本號,則予以更新,否則認為是過期數據。

Hibernate為樂觀鎖提供了3中實現:

1. 基于version

2. 基于timestamp

3. 為遺留項目添加添加樂觀鎖 

配置基于version的樂觀鎖:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3.  
  4. <hibernate-mapping> 
  5.     <class name="com.suxiaolei.hibernate.pojos.People" table="people"> 
  6.         <id name="id" type="string"> 
  7.             <column name="id"></column> 
  8.             <generator class="uuid"></generator> 
  9.         </id> 
  10.           
  11.         <!-- version標簽用于指定表示版本號的字段信息 --> 
  12.         <version name="version" column="version" type="integer"></version> 
  13.  
  14.         <property name="name" column="name" type="string"></property> 
  15.           
  16.     </class> 
  17. </hibernate-mapping> 

配置基于timestamp的樂觀鎖:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3.  
  4. <hibernate-mapping> 
  5.     <class name="com.suxiaolei.hibernate.pojos.People" table="people"> 
  6.         <id name="id" type="string"> 
  7.             <column name="id"></column> 
  8.             <generator class="uuid"></generator> 
  9.         </id> 
  10.           
  11.         <!-- timestamp標簽用于指定表示版本號的字段信息 --> 
  12.         <timestamp name="updateDate" column="updateDate"></timestamp> 
  13.  
  14.         <property name="name" column="name" type="string"></property> 
  15.           
  16.     </class> 
  17. </hibernate-mapping> 

遺留項目,由于各種原因無法為原有的數據庫添加"version"或"timestamp"字段,這時不可以使用上面兩種方式配置樂觀鎖,Hibernate為這種情況提供了一個"optimisitic-lock"屬性,它位于<class>標簽上:

  1. <?xml version="1.0" encoding="utf-8"?> 
  2. <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 
  3.  
  4. <hibernate-mapping> 
  5.     <class name="com.suxiaolei.hibernate.pojos.People" table="people" optimistic-lock="all"> 
  6.         <id name="id" type="string"> 
  7.             <column name="id"></column> 
  8.             <generator class="uuid"></generator> 
  9.         </id> 
  10.  
  11.         <property name="name" column="name" type="string"></property> 
  12.     </class> 
  13. </hibernate-mapping> 

將該屬性的值設置為all,讓該記錄所有的字段都為版本控制信息。

原文鏈接:http://www.cnblogs.com/otomedaybreak/archive/2012/01/27/2330008.html#C2

【編輯推薦】

  1. 讓Hibernate顯示SQL語句的綁定參數值
  2. Hibernate延遲加載剖析與代理模式應用
  3. 選用Ibatis和Hibernate的區別
  4. 如何在Hibernate中使用union
  5. Hibernate攔截器與監聽器
責任編輯:林師授 來源: 音①曉的博客
相關推薦

2022-09-13 13:49:05

數據庫隔離

2021-02-26 13:50:37

Java并發代碼

2009-11-25 13:33:39

并發

2009-06-24 07:51:56

Hibernate重復

2023-09-07 09:44:22

Java并發

2024-10-08 09:43:44

golang高并發加鎖事務

2021-07-01 19:31:50

并發JavaCPU

2021-06-03 14:08:03

開發技能代碼

2021-06-04 14:28:07

協程線程Android開發

2023-10-23 08:12:34

并發問題有鎖和無鎖

2023-10-20 08:01:08

2009-09-23 17:41:05

Hibernate事務

2022-04-07 14:09:50

Go工程師代碼

2009-09-24 14:43:53

Hibernate樂觀

2009-07-23 13:30:46

JDBC事務

2009-06-30 16:41:12

Hibernate的事

2009-09-23 17:52:16

Hibernate概念Hibernate常見

2011-08-12 09:52:35

iPhone開發TableviewUITextField

2013-07-23 07:24:57

iOS開發學習iOS開發問題集錦

2020-07-07 07:47:07

Java無鎖技術
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 欧美一区二区三区在线观看 | 黄色毛片在线播放 | 在线亚州 | 日本不卡免费新一二三区 | 亚洲欧美成人影院 | 9久9久9久女女女九九九一九 | 特黄色一级毛片 | 欧美精品一区二区三区在线 | 中文字幕一区在线观看视频 | 国产欧美精品一区二区色综合朱莉 | 黄瓜av | 国产免费一区二区三区免费视频 | 日韩色综合 | 在线视频成人 | 99精品免费视频 | 亚洲一级毛片 | 久久精品国产99国产精品亚洲 | av中文字幕在线 | 99精品一级欧美片免费播放 | 韩日av片 | 欧美8一10sex性hd | 日韩精品av| 日韩精彩视频 | 久久九九99| 国产一区精品 | 久久成人免费 | 国产成人福利在线观看 | 日本精品久久久久 | 岛国av免费看 | 天天曰天天曰 | 亚洲成人av一区二区 | 国产成人精品一区二区三区四区 | 日韩免费在线观看视频 | 天久久 | 欧美日韩国产中文 | 欧美三区视频 | 一级a毛片| 天天曰夜夜 | 欧美日韩亚洲国产综合 | 久久99蜜桃综合影院免费观看 | 久久国产精品免费视频 |