2011-08-01 89 views
1

我在第一次嘗試Spring,但遇到了@Transactional的問題。我的應用程序的某些部分需要在方法中記錄異常,而不是將它們冒泡到main()。但問題在於,如果發生異常,那些標有@Transactional的方法將不會回滾。有沒有更簡單的方法來結合@Transactional和日誌記錄?

總之,這不會」工作

@Transactional 
public void doStuff() { 
    try { 
     //Do something that might cause an Exception 
    } catch (Exception e) { 
     log.error("Exception when trying to do stuff", e); 
    } 
} 

因爲從我的理解交易將永遠不會被如果出現異常回滾。

唯一的解決辦法我能想出:

public void doStuff() { 
    try { 
     doStuff0(); 
    } catch (Exception e) { 
     log.error("Error encountered while attempting to join servers", e); 
    } 
} 

@Transactional 
protected void doStuff0() { 
    //Do something that might cause an Exception 
} 

這是醜陋的,雖然,使用我不喜歡的圖案,並且在這個例子中幾乎兩倍的代碼。

是否有另外一種方法記錄異常並回滾事務?

+0

順便說一句,您的解決方案不適用於JDK代理。 – Affe

回答

1

其實也有一個簡單的方法做你想做的。關於它是否是一個好主意,或者當它適當的放在一邊,建築宇航員討論有時你只需要它的工作:):

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 

易爲。

+0

OMG,建議在[documentation](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html)中推薦這種方法...推薦使用 –

+1

? :「儘管非常簡單,但這個過程非常具有侵入性,並且可以將代碼緊密結合到Spring框架的事務基礎結構中」,「強烈建議您儘可能使用聲明式方法來回滾,如果您絕對需要,可以使用程序化回滾但是,它的使用卻在實現一個乾淨的基於POJO的體系結構的過程中飛了「。 .....我不會將這種待遇稱爲'推薦':) – Affe

+0

你是對的,我剛剛在文檔中發現了這段代碼,並認爲這是一條路。我放心了 :-)。 –

0

只是重新拋出異常:

@Transactional 
public void doStuff() { 
    try { 
     //Do something that might cause an Exception 
    } catch (Exception e) { 
     log.error("Exception when trying to do stuff", e); 
     throw e; 
    } 
} 
+0

然後,異常可能會冒泡到'main()'或其他記錄方法,這意味着異常會被記錄兩次。我不確定當異常到達主線程或線程時會發生什麼,但我很確定它不好 – TheLQ

+0

它會被'@ Transactional'處理程序(不知道在什麼級別)捕獲和記錄。如果你不想要,情感的方式會更好。 – Dmitri

相關問題