2014-08-29 24 views
2

說,我有一個基本的Spring集成流程,如:例外Spring集成:如何登錄,但沒有攔截

<jms:inbound-channel-adapter> 
    <poller> 
    <transactional/> 
    </poller> 
</jms:inbound-channel-adapter> 

<some:outbound-channel-adapter/> 

如果出適配器拋出一個異常,整個事務回滾。

如果入站消息子系統支持它,該消息將被重新發送多次,直到它最終將被髮布在死信隊列中。這很好 - 除了異常本身丟失,從診斷的角度來看非常煩人。

如果我配置入口適配器與像一個錯誤的信道:

<jms:inbound-channel-adapter> 
    <poller error-channel="myErrorChannel" > 
    <transactional/> 
    </poller> 
</jms:inbound-channel-adapter> 

<some:outbound-channel-adapter/> 

然後異常被捕獲併成爲上myErrorChannel一個消息的有效載荷的一部分。然後,我可以讀取消息並將異常的堆棧跟蹤保存到日誌中以用於診斷目的 - 但價格昂貴 - 入站適配器上的事務不再回滾並且原始消息丟失 - 除非我還保存它作爲錯誤處理的一部分。

但是如果堅持異常或原始消息失敗呢?我想,如果myErrorChannel是一個直接通道,整個事務將再次回滾,最終消息將最終在死信隊列中。再次,堆棧跟蹤將丟失。

處理這些問題的最佳做法是什麼?

回答

2

其實你走正道,但是你必須手動後回滾事務日誌在你errorHandler

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); 

而這一切:沒有必要堅持消息,並擔心其他副作用存在。

當然,您的myErrorChannel必須是direct頻道才能在同一事務線程進行日誌記錄和回滾。

+0

非常感謝Artem - 再次拯救了我的一天:-) – 2014-08-31 13:39:19