Shailesh Jain
Shailesh Jain

Reputation: 79

How to prevent message redelivery from MQ Broker after camel internal redeliveries are successfully processed (transacted camel route)

I am trying to run a camel transacted() route (a standalone java process) with JPATransactionManager is the spring PlatformTransactionManager (as I want camel route to run in a single DB transaction) but I am not able to suppress redelivery from MQ Broker in case a transactional method fails even though I have used handled(true) in onException clause along with my custom redelivery policy (which is executed successfully). I only want MQ to redeliver when there is a service crash.

Tried below but it doesn't work:

Upvotes: 1

Views: 889

Answers (2)

myroch
myroch

Reputation: 163

According to the Apache Karaf Transaction Guide should doTry and doCatch work as expected. What is probably the problem in your case is the Exception triggering the error scenario. Only checked exceptions (no RuntimeException or it's descendant) don't mark ongoing transaction for rolling back.

Upvotes: 0

burki
burki

Reputation: 7005

I expect camel to try redeliveries as per redelivery policy (working) but MQ should not redeliver

When MQ must never do a redelivery (because you handle errors in Camel), you should remove acknowledgementModeName=CLIENT_ACKNOWLEDGE or explicitly set AUTO_ACKNOWLEDGE (default value).

As long as a message is not acknowledged, it is from the broker perspective not delivered. AUTO_ACKNOWLEDGE immediately acknowledges the message after consumption what makes sense if you never want to get redeliveries.

CLIENT_ACKNOWLEDGE on the other hand only acknowledges a message under certain conditions, see this post for some more info about this.

EDIT due to comment with new information

If you want MQ redeliveries, but "override" them with Camel in most cases, you have to consume messages transacted.

Use local JMS broker transactions by configuring your JMS component like this

jmsComponent.setLazyCreateTransactionManager(false);
jmsComponent.setTransacted(true);

For this type of transaction you don't need a Spring TransactionManager at all. So I guess the JPATransactionManager is ignored by JMS and your JMS consumptions should be transactional.

Now, when your Camel error handler "swallows" an Exception by using handled(true), there must be no MQ redelivery. But MQ does a redelivery when an Exception is propagated back to the broker.

I expect my camel route to run in a single db transaction

I did not find anything in your question about not working database transactions. There seems to be just one processor that does database stuff. If this is not working correctly, please describe the problem in your question or a separate question.

Upvotes: 0

Related Questions