camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Arkadi Shishlov" <arkadi.shish...@gmail.com>
Subject Re: Necessity of transactional JMS component
Date Sun, 08 May 2011 11:48:01 GMT
On Sat, 07 May 2011 17:54:11 +0300, Hanson <hanson2010@gmail.com> wrote:
> I just wonder what's the necessity of declaring a JMS component as
> transactional basically. If not, when a JMS to JMS route fails, will the
> message got lost, in case I have a DefaultErrorHandler and set redelivery
> attempts to -1?
>
> What about a File to JMS route? File component should NOT support
> transactions at all.
>
> Camel redelivery and transactions are both measures dealing with  
> exceptions.
> And in most cases, is transactions necessary? I'd like to know your idea.

If you have the Camel in Action book, Chapter 9. goes into details why and  
how transactions are working in Camel. If not, just buy an e-book, it  
worth the money 100%.
As I understand it, if the route is not transacted() then in-flight  
messages are lost in case JVM or server crashes because message retrieval  
is auto-acknowledged by the ActiveMQ. So you need transacted() to be  
correct. Non-transactional endpoints could be compensated with  
onComplete() and custom Synchronization callbacks.

But, what I believe is missing from the book is a discussion about how  
transacted route interacts with Error Handler redelivery policy. I know  
the ActiveMQ re-delivers the message (6 times, 1 sec interval by default).  
Surely this case is different, because transaction manager works with the  
same thread only, which conflicts with separate redelivery thread.
So my additional questions are:
1. Does JMS consumer always use separate re-delivery thread?
2. TransactionalErrorHandler is mentioned in in the book in Chapter 4.,  
but not discussed in Chapter 9. nor it is present in the current version  
of Camel. Whats the deal?
3. I use the following route to move the message between primary and  
secondary gateway queues based on exception thrown:

String gatewayQueue = "activemq:queue:gateway-" + gateway.getId();
ProcessorDefinition r = from(gatewayQueue).routeId("gateway-" +  
gateway.getId()); //.transacted();
r = r.onException(SipPresenceIncompatible.class)
         .maximumRedeliveries(0)
         .handled(true)
         .process(secondaryChannelProcessor)
         .end()
     .onException(Exception.class)
         .retryWhile(new Predicate() {
             public boolean matches(Exchange exchange) {
             ...
             }
             })
         .redeliveryDelay(5000)
         .backOffMultiplier(2)
         .handled(true)
         .process(secondaryChannelProcessor)
         .end()
     .filter(ContentRouteSetup.filterExpired)
     .process(removeJmsHeadersProcessor)
     .to(gatewayUrl);

It works beautifully in non-transactional mode. secondaryChannelProcessor  
moves exchanges into different gateway-# queue via ProducerTemplate or  
just discards them because they are already on secondary channel.
What I can't make a sense of is how exceptions and producer template  
interacts with the ActiveMQ rollback in transactional mode. Any hints?

Mime
View raw message