2010-10-01 34 views
4

我使用Spring 2.5的事務管理和我有以下設置:與Spring控制來自外部事務內部事務設置2.5

Bean1

@Transactional(noRollbackFor = { Exception.class }) 
public void execute() { 
    try { 
    bean2.execute(); 
    } catch (Exception e) { 
    // persist failure in database (so the transaction shouldn't fail) 
    // the exception is not re-thrown 
    } 
} 

Bean2

@Transactional 
public void execute() { 
    // do something which throws a RuntimeException 
} 

失敗永遠不會從Bean1持久到DB中,因爲整個事務被回滾。

我不想在Bean2中添加noRollbackFor,因爲它在很多沒有邏輯來正確處理運行時異常的地方使用。

有沒有一種方法可以避免只有在從Bean1調用Bean2.execute()時才能回滾事務?

否則,我想我最好的選擇是堅持我的失敗在一個新的交易?還有什麼我可以乾的?

+0

我不明白爲什麼它回滾。你是否在catch塊中重新拋出異常? – skaffman 2010-10-02 10:23:15

+0

不,我不知道。看起來它正在回滾,因爲Spring TransactionInterceptor在退出Bean2時標記了回滾事務。 – Damien 2010-10-02 18:47:26

+0

我使用REQUIRES_NEW傳播,通過在新事務中保持失敗來解決我的問題。但我很想知道是否有更好的解決方案。 – Damien 2010-10-07 14:36:51

回答

1

這是註釋的注意事項之一......您的課程不可重複使用!

如果你想用XML配置事務,如果可能的話。

假設您使用XML配置:如果它不消耗昂貴的資源,則可以創建另一個bean2實例以使用您指定的代碼。也就是說,您可以像上面指定的那樣配置一個,並且沒有任何異常回滾。

+0

謝謝,這是一個很好的評論。無論如何,我的應用程序中的整個交易設置非常糟糕,交易在DAO級別進行了聲明。正因爲如此,我仍然有一些像問題中所示的嵌入式事務,但當我有機會時,我會嘗試重構。 – Damien 2010-10-22 23:04:47