Reputation: 4064
I would like to clarify behavior of the Tibco bus (6.1) used via Spring (4.1) JMS config - with and without ErrorHandler specified, and for a specific case of the TransactionRolledBackException.
I configure JMS listener with the "transacted" mode as following:
<jms:listener-container connection-factory="singleConnectionFactory"
acknowledge="transacted" task-executor="myTaskExecutor" concurrency="${my.queue.concurrency}">
<jms:listener destination="${queue.destination}" ref="myProcessor" method="processMyMessage" />
</jms:listener-container>
and also set 'maxRedelivery' for the queue to 2.
Here are the scenarios of processing an event in the myProcessor.processMyMessage():
Now, I am adding an explicit ErrorHandler to better log some runtime exceptions:
<jms:listener-container connection-factory="singleConnectionFactory"
acknowledge="transacted" task-executor="myTaskExecutor" concurrency="${my.queue.concurrency}"
error-handler="myErrorHandler">
<jms:listener destination="${queue.destination}" ref="myProcessor" method="processMyMessage" />
</jms:listener-container>
And the following implementation of the ErrorHandler, where we swallow TransactionRolledBackException:
import org.springframework.jms.TransactionRolledBackException;
import org.springframework.util.ErrorHandler;
public class JMSListenerErrorHandler implements ErrorHandler {
@Override
public void handleError(Throwable t) {
if (t.getCause() instanceof TransactionRolledBackException) {
log.warn("JMS transaction rollback; reason: " + t.getMessage(), t);
} else {
log.error(t.getMessage(), t);
throw new RuntimeException(t);
}
}
What is going to happen for each of the use cases? Here is my guess:
Couple more questions:
Thank you,
Marina
Upvotes: 0
Views: 1309
Reputation: 174729
Spring JMS only throws that exception when the underlying JMS client throws a javax.jms.TransactionRolledBackException
- it is simply an unchecked wrapper exception - see JmxUtils.convertJmsAccessException()
.
Take a look at the stack trace and you will see where/why it was thrown.
In general, i.e. if it was thrown on the container's session, catching it won't have any effect - the transaction is already rolled back; but the stack trace is the key.
Upvotes: 1