Hibernate 事物隔離級別 深入探究

目錄

一、數據庫事務的定義

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

三、數據庫事務隔離級別

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

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

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

?

??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的樂觀鎖:

復制代碼
復制代碼
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.suxiaolei.hibernate.pojos.People" table="people">
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>

<!-- version標簽用于指定表示版本號的字段信息 -->
<version name="version" column="version" type="integer"></version>

<property name="name" column="name" type="string"></property>

</class>
</hibernate-mapping>
復制代碼
復制代碼

配置基于timestamp的樂觀鎖:

復制代碼
復制代碼
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.suxiaolei.hibernate.pojos.People" table="people">
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>

<!-- timestamp標簽用于指定表示版本號的字段信息 -->
<timestamp name="updateDate" column="updateDate"></timestamp>

<property name="name" column="name" type="string"></property>

</class>
</hibernate-mapping>
復制代碼
復制代碼

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

復制代碼
復制代碼
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.suxiaolei.hibernate.pojos.People" table="people" optimistic-lock="all">
<id name="id" type="string">
<column name="id"></column>
<generator class="uuid"></generator>
</id>

<property name="name" column="name" type="string"></property>
</class>
</hibernate-mapping>
復制代碼
復制代碼

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

轉載于:https://www.cnblogs.com/jiligalaer/p/3990369.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/258164.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/258164.shtml
英文地址,請注明出處:http://en.pswp.cn/news/258164.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Linked List Cycle II - LeetCode

Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note: Do not modify the linked list. Follow up:Can you solve it without using extra space? 思路&#xff1a;維護兩個指針slow和fast。先判斷是否存在環。 在判斷是否…

mysql 無論輸入什么都是現實 not found_NotAPanda

前言面試競爭力越來越大&#xff0c;是時候擼一波Vue和React源碼啦&#xff1b;本文從20個層面來對比Vue和React的源碼區別&#xff1b;如果需要了解API的區別&#xff0c;請戳&#xff1a;Vue 開發必須知道的 36 個技巧React 開發必須知道的 34 個技巧文章源碼&#xff1a;請戳…

這五張PPT告訴你,如何打造無人駕駛“最強大腦”

“英特爾在談無人駕駛&#xff0c;會成為汽車制造商嗎?NO!我們要為無人駕駛提供從車、連接到云的‘最強大腦’。” 在昨天于北京舉行的英特爾無人駕駛分享會上&#xff0c;英特爾無人駕駛事業部中國區市場總監徐偉杰在主旨演講中開門見山。 這也是英特爾無人駕駛事業部去年11月…

javascript之ua與urlSchema

我們首先拿到瀏覽器ua: 1 var ua navigator.userAgent; 1 if (ua.indexOf("MicroMessenger") > -1) { 2 alert("微信瀏覽器"); 3 } 1 if (ua.indexOf("iPhone") > -1) { 2 alert("iphone"); 3 } 其…

ezdpl Linux自動化部署實戰

最近把ezdpl在生產環境中實施了&#xff0c;再加上這段時間的一些修改&#xff0c;一并介紹一下。再次申明&#xff1a; ezdpl不是開箱即用的&#xff0c;需要根據自己的應用環境定制。對初學者來說使用起來反倒困難更多、風險更大。它不是一個通用的項目&#xff0c;更多的是提…

無法打開輸入文件mysql_錯誤LNK1181,pip安裝“無法打開輸入文件”mysqlclient.lib'...

我是Python新手&#xff0c;正在嘗試安裝mysql模塊&#xff0c;但是在解決了其他5個問題之后&#xff0c;我現在遇到了一個問題&#xff0c;當我嘗試安裝該模塊時&#xff0c;會出現以下日志&#xff1a;PS C:\Users\poste> pip install mysqlCollecting mysqlUsing cached …

俄羅斯將封殺LinkedIn 推動個人數據本地化

北京時間11月11日上午消息&#xff0c;莫斯科一家法院本周四支持了在俄羅斯封殺職業社交網站LinkedIn的決定。 俄羅斯聯邦通信監管局&#xff08;Roskomnadzor&#xff09;之前要求國內外企業從2015年9月開始&#xff0c;必須將所有俄羅斯用戶的個人數據存儲在該國境內。Linked…

python的datetime舉例_Python datetime模塊的使用示例

1、獲取當前年月日時分秒# -*- encodingutf-8 -*-import datetimenow datetime.datetime.now()print("now:{}".format(now))year now.yearprint("year:{}".format(year))month now.monthprint("month:{}".format(month))day now.dayprint(&q…

vs2015 去除 git 源代碼 綁定,改成向tfs添加源碼管理

除了下文的方法是將源碼管理從git改成tfs之外&#xff0c;還要做以下幾步即可 向tfs添加源碼 打開源碼管理(管理連接)&#xff0c;雙擊打開你要向其中添加的tfs連接選中該解決方案&#xff0c;右鍵 將解決方案添加到源碼管理嵌入完畢vs2015 去除 git 源代碼 綁定 第一次碰到這個…

HDU 4609 FFT

題目大意 給定n條邊的邊值&#xff0c;求任意取三條邊能組成三角形的概率 這里概率 P valid/tot tot (n-2)*(n-1)*n/6是沒問題的 valid表示合法的方式 先考慮&#xff0c;任意兩條邊組合形成方法的總數 因為邊值在100000的范圍內&#xff0c;這里組合用fft計算 得到最后形成和…

《日志管理與分析權威指南》一2.3 良好日志記錄的標準

本節書摘來華章計算機《日志管理與分析權威指南》一書中的第2章 &#xff0c;第2.3節&#xff0c;&#xff08;美&#xff09; Anton A. Chuvakin Kevin J. Schmidt Christopher Phillips 著 姚 軍 簡于涵 劉 暉 等譯更多章節內容可以訪問云棲社區“華章計算機”公眾號查…

Python【01】【基礎部分】- A

一、WHATS PYTHON ? 1、python 簡介 Python&#xff08;英語發音&#xff1a;/?pa?θ?n/&#xff09;, 是一種面向對象、解釋型計算機程序設計語言&#xff0c;由Guido van Rossum于1989年發明&#xff0c;第一個公開發行版發行于1991年。Python是純粹的自由軟件&#xff0…

java的自增自減_Java中自增和自減操作符(++/--)的那些事

自增()和自減(--)運算符在JAVA語言中存在著很多運算符&#xff0c;但是在實際開發中我們或許很少用到它們&#xff0c;在初次學習中卻時常出現它們的身影&#xff0c;對于這些運算符的含義和用法&#xff0c;是否還記得呢&#xff1f;1. 概述自增操作符()和自減操作符(--)是對變…

Finished yeah!

終于到了最后的博客階段&#xff0c;這時候才知道博客此時此刻是多么的愜意&#xff0c;它成了書寫心聲的自由平臺&#xff01;耗時一天完成這作業說起來也是蠻辛苦的&#xff0c;編譯器需要新裝&#xff0c;IDE需要熟悉&#xff0c;當然最主要的是之前淺入淺出的C功底在此次作…

《Python語言程序設計》——1.6 開始學習Python

本節書摘來自華章計算機《Python語言程序設計》一書中的第1章&#xff0c;第1.6節,作者&#xff1a;&#xff3b;美&#xff3d;梁勇&#xff08;Y. Daniel Liang&#xff09; 更多章節內容可以訪問云棲社區“華章計算機”公眾號查看。 1.6 開始學習Python 關鍵點&#xff1a;…

Tomcat性能調優

1、集成apache 雖然Tomcat也可以作web服務器&#xff0c;但是處理靜態html的速度比不上apache&#xff0c;且其作為web服務器的功能遠不如Apache&#xff0c;因此把apache和tomcat集成起來&#xff0c;講html和jsp功能部分進行明確的分工&#xff0c;讓tomcat只處理jsp部分&…

【轉】sip中的subscribe和notify擴展應用技術

http://blog.csdn.net/hwz119/article/details/3965322轉載于:https://www.cnblogs.com/matthew-2013/p/4917207.html

再讀《被神化的框架》

開發框架&#xff0c;構件&#xff0c;組件非常地多&#xff0c;而且&#xff0c;趨勢是越來越多&#xff0c;特別是在java中。當然也不是說其它平臺的少。而特別是框架越來越被神化了&#xff0c;似乎用之解決一切問題&#xff0c;不用就要敲壞鍵盤。對于老衲這樣的打字員來說…

河南推出近萬億PPP投資計劃 鄭州實現智慧城市全覆蓋

1 近萬億PPP項目啟動 眼下&#xff0c;國內財經新聞的熱點聚焦在PPP開發上&#xff0c;這與PPP支撐國內經濟平衡運行的一支強勁力量正被政府看好。就連二級市場也出現了PPP概念的搶籌現象。 9月27日&#xff0c;股市再一次遭遇拋售&#xff0c;大盤創出階段性新低&#xff0c;然…

java基礎實例代碼_Java基礎實例

打印等腰三角形代碼public class ForForTest{public static void main(String []args){for(int x0;x<5;x){for(int yx1;y<5;y){System.out.print(" ");}for(int z0;zSystem.out.print("* ");}System.out.println();}}}折半查找代碼&#xff1a;//練習…