问题
Say that I have a basic Spring Integration flow like:
<jms:inbound-channel-adapter>
<poller>
<transactional/>
</poller>
</jms:inbound-channel-adapter>
<some:outbound-channel-adapter/>
If the outbound adapter throws an exception the entire transaction is rolled back.
If the inbound message subsystem supports it the message will be redelivered a number of times until it will eventually be posted on the Dead Letter Queue. This is fine - except that the exception itself is lost which is very annoying from a diagnostic point of view.
If I configure the inbound adapter with an error-channel like:
<jms:inbound-channel-adapter>
<poller error-channel="myErrorChannel" >
<transactional/>
</poller>
</jms:inbound-channel-adapter>
<some:outbound-channel-adapter/>
then the exception is caught and becomes part of the payload of a message on myErrorChannel. I can then read the message and persist the stack trace of the exception to a log for diagnostic purposes - but at a price - the transaction on the inbound adapter is no longer rolled back and the original message is lost - unless I save it as well as part of the error handling.
But what if persisting the exception or the original message fails as well? I suppose that if myErrorChannel is a direct channel the entire transaction will again be rolled back and eventually the message will end up on the Dead Letter Queue. And once more the stack trace will be lost.
What is the best practice for dealing with these issues?
回答1:
Actually you go right way, but you have to rollback transaction manually after log it in your errorHandler
:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
And that's all: no need to persist message and worry about other side effects there.
Of course, your myErrorChannel
has to be direct
channel to do logging and rolback at the same transactional thread.
来源:https://stackoverflow.com/questions/25566934/exceptions-in-spring-integration-how-to-log-but-not-intercept