I am working with a command-event driven system using JMS and Apache Camel for for routing. In the following situation:
I send the system a request-reply command "X".
The system receives "X" via a transacted camel route.
While processing "X" the system sends out several events, "Y" & "Z", but as its part of the transacted route these should not be flushed until the transaction has completed.
An runtime exception occurs - which should cause the transaction to rollback.
I want to be able to intercept the exception and reply with a genuine message (rather than exception) to the client. As such I started to implement an error handler:
onException(RuntimeException.class)
.handled(true)
.markRollbackOnly()
.filter(header(Header.REPLY_TO.getName()).isNotNull())
.to(DESTINATION_FOR_EXCEPTION_HANDLING)
.to(DESTINATION_FOR_REPLIES);
Where:
The problem I have is that if I include "markRollbackOnly()" it:
And If i don't include it, then:
How can I configure camel to both prevent the flushing of messages in the transaction, and yet be able to convert the exception to a handled error message?
I tried Claus approach but couldn't get it to work for some reason, I must have misunderstood or setup something incorrectly.
Eventually I solved this by propagating a second transaction internally, one the error handler I could then "markRollbackOnlyLast" the second transaction, but respond with a "good" message on the primary transaction:
TransactionTemplate newTransactionTemplate = new TransactionTemplate(platformTransactionManager);
newTransactionTemplate.setPropagationBehavior(PROPAGATION_REQUIRES_NEW);
Policy requireNewTransaction = new SpringTransactionPolicy(newTransactionTemplate);
onException(RuntimeException.class)
.onWhen(header(Header.REPLY_TO.getName()).isNotNull())
.log(LoggingLevel.ERROR, EXCEPTION_STACKTRACE)
.to(PROCESSOR_FOR_EXCEPTION_HANDLING)
.to(PROCESSOR_FOR_REPLY)
.handled(true)
.markRollbackOnlyLast();
from(FROM)
.policy(requireNewTransaction)...