當前位於具有本地和遠程EJB的MDB(Singleton和Stateless)的JavaEE應用程序服務器中,我正在使用JDBC-Transactions for Hibernate Core。在拋出異常時回滾事務並關閉連接
管理自己我所有的開啓和關閉,提交休眠會話和事務可能導致連接泄漏和未合併的事務。
特別是在編程錯誤導致自定義或未經檢查的異常未捕獲並拋出到遠程客戶端的情況下。
什麼是最簡單或最好的方式來確保我的休眠會話被關閉,事務回滾以防錯誤發生?
使用容器管理的事務(CMT)還是可以關閉在任何EJB方法返回時調用的攔截器內的會話?
一個簡單的方法是將會話範圍的用法包裝在try-catch塊中,並捕獲任何類型的異常,但採用較少代碼的一般方法會受到青睞。
編輯:遠程EJB實例
我低級別的Hibernate DAO不關閉連接和拋出的異常回滾事務。問題是業務邏輯之間的DAO訪問的情況下,連接仍處於打開*
public void doSomething(Foo foo) throws Exception { // open session and transaction Session session = DAO.openSession(); // retrieve data Bar bar = DAO.get(session, ...) // call other methods which throws an exception resulting in open connection doOtherStuff(foo, bar) DAO.save(session, foo); // commit transaction DAO.closeAndCommitSession(session); }
現在我使用的是大的try-catch-最後:
public void doSomething(Foo foo) throws Exception
{
// open session and transaction
Session session = DAO.openSession();
try
{
// retrieve data
Bar bar = DAO.get(session, ...)
// call other methods which throws an exception resulting in open connection
doOtherStuff(foo, bar)
DAO.save(session, foo);
}
catch (final Exception e)
{
DAO.rollBackTransaction(session);
throw e;
}
finally
{
DAO.closeAndCommitSession(session);
}
}
這將需要每個方法的'ConnectionRunnable',這似乎是非常大的開銷。關閉連接是最低優先級,因爲這只是一個編程錯誤。問題更多的是未捕獲的異常,當連接仍處於打開狀態並且事務未回滾時,將拋出異常。 – djmj
@djmj:Beryllium提出的解決方案看起來簡潔而優雅,即使它需要每個連接的匿名內部類。這裏的美妙之處在於,它允許您以更確定的方式管理資源並處理異常。我錯過了什麼嗎? – scottb
@scottb不錯的總結!我只想補充說,在使用站點上需要更少的代碼行:嵌套的異常處理在每個使用站點都會使代碼混亂。 – Beryllium