2014-10-06 63 views
0

我試圖用Hibernate保存數據。一切都在同一會話中進行。該邏輯如下:Hibernate事務從另一個事務拋出異常

1)開始交易,並試圖保存:

try 
{ 

    session.getTransaction().begin(); 
    session.save(result); 
    session.getTransaction().commit(); 
} 
catch (Exception e) 
{ 
    session.getTransaction().rollback(); 
    throw e; 
} 

2)如果一個新的記錄違反完整性約束趕在外包裝法例外,打開另一個事務及查詢更多數據

catch (ConstraintViolationException e) 
{ 
    if ("23000".equals(e.getSQLException().getSQLState())) 
    { 
    ... 

    session.getTransaction().begin(); 
    Query query = session.createQuery("from Appointment a where a.begin >= :begin and a.end <= :end"); 
    query.setDate("begin", date); 
    query.setDate("end", DateUtils.addDays(date, 1)); 

    List results = query.list(); 
    session.getTransaction().commit(); 

問題是,當第二事務執行query.list它拋出should'be被與前一事務鏈接異常。

SQLIntegrityConstraintViolationException:ORA-00001:唯一約束

我應該從另一個會話查詢數據或者有什麼其他的方式來彼此隔離兩筆交易?

謝謝!

+0

我想在第二種情況下,當拋出異常並且稍後查詢第二個事務時,必須回滾catch塊中的第一個事務。目前您剛剛開始第二筆交易時出現錯誤,因爲第一筆交易尚未回滾 – vikeng21 2014-10-06 04:42:52

+0

@ vikeng21,不是真的,第一個模塊擁有自己的「catch(Exception e)」,它會回滾第一筆交易。然後它重新拋出一個異常,它被第二個塊捕獲,第二個事務開始。 – andreybavt 2014-10-06 04:47:18

+0

哦,好吧,它們是代碼的相同部分,但是您的異常hirerchy不正確,您的會話對象是全局權限。你可以嘗試創建一個新的會話對象,因爲我們可以創建會話對象的每個事務。你的異常看起來像插入相關,但你實際上運行一個選擇查詢不知道爲什麼你得到它 – vikeng21 2014-10-06 04:56:03

回答

1

,如果你得到一個異常,則不應使用同一個會話,你必須關閉會話,並使用不同的會話你的第二個操作。這是送給Hibernate文檔中:

13.2.3 Exception Handling

如果Session拋出異常,包括任何的SQLException, 立即回滾數據庫事務,調用Session.close() ,丟棄該Session實例。會話的某些方法不會 使會話保持一致狀態。 沒有拋出異常Hibernate可以被視爲可恢復。通過在finally塊中調用close()來確保會話將會關閉 。

0

希望Exception類是所有類型異常的基礎,因此如果在它被放置之前它將被捕獲並且其餘的異常處理被隔離。

+0

在調試器中,我真的首先在'catch(Exception e) {session.getTransaction() .rollback(); 扔e; }' block然後在第二個catch(ConstraintViolationException e)塊中。所以我提到的所有代碼都是可以訪問的。問題在於每筆交易的範圍以及爲什麼它們都是混合的 – andreybavt 2014-10-06 05:07:44