Java程式員從笨鳥到菜鳥之(六十五)細談Hibernate(十六)資料庫事務與隔離等級

來源:互聯網
上載者:User



           資料庫事務:事務是指一組相互依賴的操作行為,如銀行交易、股票交易或網上購物。事務的成功取決於這些相互依賴的操作行為是否都能執行成功,只要有一個操作行為失敗,就意味著整個事務失敗。關於事務的一個經典例子就是:A到銀行辦理轉賬事務,把100元錢轉到B的帳號上,這個事務包含以下操作行為: 

(1)從A的賬戶上減去100元。 

(2)往B的賬戶上增加100元。

      顯然,以上兩個操作必須作為一個不可分割的工作單元。假如僅僅第一步操作執行成功,使得Tom的賬戶上扣除了100元,但是第二步操作執行失敗,Jack的賬戶上沒有增加100元,那麼整個事務失敗。 資料庫事務是對現實生活中事務的類比,它由一組在商務邏輯上相互依賴的SQL語句組成。 

 下面我們一起來看一下資料庫事務的生命週期:

                                             

這個資料庫事務的生命週期圖反應出資料庫事務的三個邊界:

1.事務的開始邊界。 

2.事務的正常結束邊界(COMMIT):提交事務,永久儲存被事務更新後的資料庫狀態。 

3.事務的異常結束邊界(ROLLBACK):撤銷事務,使資料庫退回到執行事務前的初始狀態。 

其實每個資料庫連接都有個全域變數@@autocommit,表示當前的事務模式,它有兩個可選值: 0:表示手工提交模式。 1:預設值,表示自動認可模式。 

在自動認可模式下,每個SQL語句都是一個獨立的事務。也就是說,每執行一條sql語句,資料庫都會自動認可這個事務,當我們用資料庫另一個用戶端去查詢的時候,我們可以看到這個新修改或插入的資料。在手工提交模式下,必須顯式指定事務開始邊界和結束邊界: 

–事務的開始邊界:begin 

–提交事務:commit 

–撤銷事務:rollback 

下面我們來看一下通過JDBC API是如何聲明事務邊界的:

Connection提供了以下用於控制事務的方法: 

1.setAutoCommit(boolean autoCommit):設定是否自動認可事務 

2.commit():提交事務 

3.rollback():撤銷事務 

下面我們看一下具體的應用樣本:

try { con = java.sql.DriverManager.getConnection(dbUrl,dbUser,dbPwd); //設定手工提交事務模式 con.setAutoCommit(false); stmt = con.createStatement(); //資料庫更新操作1 stmt.executeUpdate("update ACCOUNTS set BALANCE=900 where ID=1 "); //資料庫更新操作2 stmt.executeUpdate("update ACCOUNTS set BALANCE=1000 where ID=2 "); con.commit(); //提交事務 }catch(Exception e) { try{ con.rollback(); //操作不成功則撤銷事務 }catch(Exception ex){ //處理異常 …… } //處理異常 …… }finally{…} 

       看到上邊的樣本我們可以看出,其實hibernate事務邊界就是模仿者JDBC的事務邊界來的,其實在hibernate底層的交易管理就是利用的JDBC的交易管理。我們來看一下hibernate事務邊界:

1.聲明事務的開始邊界: 

Transaction tx=session.beginTransaction(); 

2.提交事務: tx.commit(); 

3.撤銷事務: tx.rollback(); 

       我們在學習JDBC資料庫交易管理的時候,重點也是痛點的學習了jdbc多個事務並發問題。既然hibernate底層是用JDBC交易管理實現的,那麼它也一定存在著多個事務並發的問題。下面我們就具體來看一下:hibernate多個事務並發的並發問題:

•第一類丟失更新:撤銷一個事務時,把其他事務已提交的更新資料覆蓋。 

•髒讀:一個事務讀到另一事務未提交的更新資料。 

•虛讀:一個事務讀到另一事務已提交的新插入的資料。 

•不可重複讀取:一個事務讀到另一事務已提交的更新資料。 

•第二類丟失更新:這是不可重複讀取中的特例,一個事務覆蓋另一事務已提交的更新資料。 

下面我們就髒讀來舉一個樣本:

                                            

取款事務在T5時刻把存款餘額改為900元,支票轉賬事務在T6時刻查詢賬戶的存款餘額為900元,取款事務在T7時刻被撤銷,支票轉賬事務在T8時刻把存款餘額改為1000元。 由於支票轉賬事務查詢到了取款事務未提交的更新資料,並且在這個查詢結果的基礎上進行更新操作,如果取款事務最後被撤銷,會導致銀行客戶損失100元。 

交易隔離等級

關於交易隔離等級,我們來看一下下面的兩個圖解:

                                  

                                    

由可以看出:隔離等級越高,越能保證資料的完整性和一致性,但是對並發效能的影響也越大。 對於多數應用程式,可以優先考慮把資料庫系統的隔離等級設為Read Committed,它能夠避免髒讀,而且具有較好的並發效能。儘管它會導致不可重複讀取、虛讀和第二類丟失更新這些並發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖或樂觀鎖來控制。 

下面我們就具體來看一下hibernate怎麼來配置隔離等級:在Hibernate的設定檔中可以顯式的設定隔離等級。每一種隔離等級都對應一個整數: 

1:Read Uncommitted 

2:Read Committed 

4:Repeatable Read 

8:Serializable 

例如,以下代碼把hibernate.cfg.xml檔案中的隔離等級設為Read Committed: 

hibernate.connection.isolation=2 

對於從資料庫連接池中獲得的每個串連,Hibernate都會把它改為使用Read Committed隔離等級。 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.