Hibernate設置事務的隔離級別


方式有兩種:

1)修改配置文件hibernate.cfg.xml實現

<hibernate-configuration>
 
    <session-factory>
 
        ......
 
        <!--  事務隔離級別 
            0:TRANSACTION_NONE
            1:TRANSACTION_READ_UNCOMMITTED
            2:TRANSACTION_READ_COMMITTED
            4:TRANSACTION_REPEATABLE_READ
            8:TRANSACTION_SERIALIZABLE
        -->
        <property name="hibernate.connection.isolation">4</property>
 
        ......
 
    </session-factory>
 
</hibernate-configuration>

2)代碼方式

Session session = sessionFactory.openSession();
session.connection().setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);

Serializable:串行化。隔離級別最高 
Repeatable Read:可重復讀 
Read Committed:已提交數據讀 
Read Uncommitted:未提交數據讀。隔離級別最差 
設置鎖:樂觀鎖和悲觀鎖。 
樂觀鎖:使用版本號或時間戳來檢測更新丟失,在的映射中設置 optimistic-lock=”all”可以在沒有版本或者時間戳屬性映射的情況下實現 版本檢查,此時Hibernate將比較一行記錄的每個字段的狀態 行級悲觀鎖:Hibernate總是使用數據庫的鎖定機制,從不在內存中鎖定對象!只要為JDBC連接指定一下隔 離級別,然后讓數據庫去搞定一切就夠了。類LockMode 定義了Hibernate所需的不同的鎖定級別:LockMode.UPGRADE,LockMode.UPGRADE_NOWAIT,LockMode.READ;

隔離級別

Serializable(串行化):可避免臟讀、不可重復讀、虛讀情況的發生。

Repeatable read(可重復讀):可避免臟讀、不可重復讀情況的發生。

Read committed(讀已提交):可避免臟讀情況發生。

Read uncommitted(讀未提交):最低級別,以上情況均無法保證。

總結:Serializable隔離級別,雖然可避免所有問題,但性能、效率是最低的,原因是它采取的是鎖表的方式,即單線程的方式,即有一個事務來操作這個表了,另外一個事務只能等在外面進不來。隨着隔離級別的增高,並發性能降低,隨之會引發運行的性能、效率問題

臟讀 dirty reads:當事務讀取還未被提交的數據時,就會發生這種事件。舉例來說:Transaction 1 修改了一行數據,然后 Transaction 2 在 Transaction 1 還未提交修改操作之前讀取了被修改的行。如果 Transaction 1 回滾了修改操作,那么 Transaction 2 讀取的數據就可以看作是從未存在過的。


不可重復的讀 non-repeatable reads:當事務兩次讀取同一行數據,但每次得到的數據都不一樣時,就會發生這種事件。舉例來說:Transaction 1 讀取一行數據,然后 Transaction 2 修改或刪除該行並提交修改操作。當 Transaction 1 試圖重新讀取該行時,它就會得到不同的數據值(如果該行被更新)或發現該行不再存在(如果該行被刪除)。
虛讀 phantom read:如果符合搜索條件的一行數據在后面的讀取操作中出現,但該行數據卻不屬於最初的數據,就會發生這種事件。舉例來說:Transaction 1 讀取滿足某種搜索條件的一些行,然后 Transaction 2 插入了符合 Transaction 1 的搜索條件的一個新行。如果 Transaction 1 重新執行產生原來那些行的查詢,就會得到不同的行。

 

臟讀:在一個事務中讀取到另一個事務沒有提交的數據
不可重復讀:在一個事務中,兩次查詢的結果不一致(針對的update操作)
虛讀(幻讀):在一個事務中,兩次查詢的結果不一致(針對的insert操作)
通過設置數據庫的隔離級別來避免上面的問題(理解)
read uncommitted 讀未提交 上面的三個問題都會出現
read committed 讀已提交 可以避免臟讀的發生
repeatable read 可重復讀 可以避免臟讀和不可重復讀的發生
serializable 串行化 可以避免所有的問題

起初隔離級別為read uncommitted 讀未提交;a,b兩個會話,分別開啟兩個事務,然后a向b轉了500元錢,但a未提交該事務,
此時b查看,發現多了500.然后a回滾事務,b再查看賬戶,發現根本就沒有多500.這便是臟讀。
臟讀便是可以讀取到另一個事務尚未提交的數據。
如果我們此時將隔離級別提升為read committed 讀已提交,便可避免臟讀。同樣b兩個會話,分別開啟兩個事務,然后a向b轉了500元錢,
但a未提交該事務,此時b查看,依舊是原錢數.
但此時,如果a 提交事務,b再去查看,發現此時多了500,對b而言,在一個事務中,兩次查詢的結果不一致,這便是不可重復讀。
如果我們此時將隔離級別提升為repeatable read 可重復讀,可以避免臟讀和不可重復讀的發生。同樣a 提交事務,b再去查看,發現
依舊是原錢數,b只能結束當前事務,在開啟一個新事務,才能查詢到數據的變化,這al便避免了不可重復讀。
如果我們設置了seriizable串行化,就相當於鎖表,某一時間內只允許一個事務訪問該表。

 

補充:關於事務,在面試中被問到的概率是很高的,可以問的問題也是很多的。
首先需要知道的是,只有存在並發數據訪問時才需要事務。當多個事務訪問同一數據時,
可能會存在5類問題,包括3類數據讀取問題(臟讀、不可重復讀和幻讀)和2類數據更新問題(第1類丟失更新和第2類丟失更新)。
第1類丟失更新:事務A撤銷時,把已經提交的事務B的更新數據覆蓋了。
第2類丟失更新:事務A覆蓋事務B已經提交的數據,造成事務B所做的操作丟失。

隔離級別臟讀不可重復讀幻讀第一類丟失更新第二類丟失更新

READ UNCOMMITED允許允許允許 不允許 允許

READ COMMITTED不允許允許允許 不允許 允許

REPEATABLE READ不允許不允許允許 不允許 不允許

SERIALIZABLE不允許不允許不允許 不允許 不允許


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM