2010-08-27 84 views
6

一切我讀到休眠狀態,你必須給出一個例子回滾事務,並在發生錯誤時關閉會話,並且通常會有下面的代碼(由Hibernate的文檔拍攝)的一些變化:如果您不在Hibernate中回滾事務,會發生什麼情況?

Session sess = factory.openSession(); 
Transaction tx = null; 
try { 
    tx = sess.beginTransaction(); 
    // do some work 
    ... 
    tx.commit(); 
} catch (RuntimeException e) { 
    if (tx != null) tx.rollback(); 
    throw e; // or display error message 
} finally { 
    sess.close(); 
} 

由於幾個原因,這種模式對我來說似乎很奇怪。首先,對於一個通常旨在簡化事情的框架來說,看起來似乎過於複雜。更重要的是,如果try塊中的代碼拋出RuntimeException以外的內容,會發生什麼情況?看起來好像Hibernate必須能夠在這種情況下正常關閉會話,大概是通過回滾,但如果這是真的,爲什麼還要打電話rollback

+2

誰告訴你Hibernate使事情變得簡單? :) – skaffman 2010-08-27 20:54:45

回答

4

Hibernate可能使很多事情變得簡單,但事務管理並不是很簡單,所以對於每一個事務你都必須非常仔細地考慮你想要的東西。 Hibernate無法幫助你。

如果try塊中的代碼拋出除RuntimeException之外的任何內容,那麼您的事務顯然不會提交。但是你也沒有明確地回滾。您的finally區塊中的sess.Close呼叫不會回滾事務。發生什麼取決於這是否是嵌套事務:

  • 如果不是,則最終事務超時並回滾。
  • 如果是這樣,父事務將看到子事務在提交時沒有提交。這將導致整個事務的回滾。
0

更重要的是,如果在try塊中的代碼比拋出一個RuntimeException其他 會出現什麼情況?

如果RuntimeException之外的try塊中的代碼塊中有任何其他異常,那麼這必須是一個檢查異常,它會被編譯器自己捕獲,並且最終會導入併入它的處理部分在你的代碼中。

在這個問題提供的例子中,我們只捕獲RuntimeException,這是我認爲是正確的代碼編寫方式。通過這樣做,我們可以立即回滾事務,而無需等待事務超時和最終回滾。當我們繼續拋出RuntimeException時,我們也沒有打破異常流程。這是更清晰和更明確的處理事務的方式,而不是讓事務超時觸發事務的回滾。

當然,我們不應該以捕獲RuntimeException的方式捕獲'Exception',原因很明顯。

相關問題