2013-08-27 80 views
2

請考慮以下代碼片段。 (我使用Spring 3.1和Hibernate 3.6)Spring @Transaction註釋和異常處理

@Override 
@Transactional 
public <T extends Termination> void progressToPendingStage(Class<T> entity, 
     Long terminationId, String userName) throws Exception { 

    Termination termination = findTerminationById(entity, terminationId); 
    //TODO improvise such that email does not get sent if data is not saved 
    if (termination.getStatus().equals(TerminationStatus.BEING_PREPARED.toString())) { 
     termination.setStatus(TerminationStatus.PENDING.toString()); 
     termination.setSubmittedDate(new Date()); 
     termination.setSubmittedBy(userName); 
     saveOrUpdateTermination(termination); 
     //Send an email to SAS 
     emailHelper.configureEmailAndSend(termination); 
    } 

} 

對於上述方法單位測試表明,電子郵件無論如何都會收到該saveOrUpdateTermination(終止)拋出異常與否。在進一步的測試和一些研究中,我發現這種行爲是預期的行爲。這不符合商業規則的要求。只有終止記錄保存成功時才應發送電子郵件。有關如何使其以所需方式行事的建議?我能想到的一種方法是讓調用者處理progressToPendingStage方法引發的異常,並且如果沒有異常發送,則發送電子郵件。我在正確的軌道上,還是可以改變@Transaction行爲的方式。

+0

您可以參考關於春季交易的[此鏈接](http://stackoverflow.com/questions/1099025/spring-transactional-what-happens-in-background)。 – brucefeng

+0

它看起來像電子郵件發件人不是由交易管理器管理的,在這種情況下,電子郵件是在提交周圍交易之前發送的 –

+0

@ArunPJohny電子郵件助手用@@ Service註釋進行了註釋。我是否也應該使用configureEmailAndSend()方法@@ Transactional?這是你的建議嗎?請您提供更多信息。 – Khush

回答

0

我已經通過圍繞這個問題設計解決了這個問題。發送電子郵件並不意味着成爲交易的一部分。我創建了一個執行保存後任務的對象。該對象將捕獲保存終止時拋出的異常,如果沒有異常拋出,我會觸發一個電子郵件發送出去。人們也可以把它放在一個Spring Aspect中,它可以在成功保存後成功返回時執行。

課程learn't:不包含不屬於@transaction標記的方法的步驟。如果它包含在一個事務中,Spring將默默地處理這個異常,並且不會拋出異常直到事務完成。 簡而言之,如果使用@Transaction註釋一個方法,則即使該方法中間的一行會拋出異常,該方法中的每一行都將被執行。