You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@camel.apache.org by leroykendall <le...@yahoo.com> on 2013/04/08 17:03:46 UTC

JMS transaction behavior inside of route

Hi,

The standard JMS transaction looks like:

    session = connection.createSession( true, -1 );
    queue = session.createQueue( "queue.name" );
    consumer = session.createConsumer( queue );

    // Messages processing loop
    try {
        message = consumer.receive();       // Receive message from queue
        ...
        messageFlow( message );
        anotherMessageFlow( message );
        ...
        session.commit();          // Message acknowledge
    } catch (Exception ex) {
        session.rollback();         // Put message back to queue for
redelivery
    }

Question: can we do similar behavior in Camel route?
So it would look like:

    <route>
        <from uri="jms:queue:queue.name"/>    <|-- Receive message from
queue, but don't do acknowledge yet. -->
        ...
        <bean ref="messageFlow"/>
        <bean ref="anotherMessageFlow"/>     <|-- If exception is thrown
here then do rollback of message back to JMS queue for redelivery. -->
    </route>                                            <|-- End of route.
Do JMS session commit and message acknowledge. -->

So can Camel 2.10.0 do this?

Thanks.
--Victor



--
View this message in context: http://camel.465427.n5.nabble.com/JMS-transaction-behavior-inside-of-route-tp5730513.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JMS transaction behavior inside of route

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Thanks for sharing this.

I wrote a blog entry years ago how you can configure Camel to show
some details about external redelivered messages from a message broker
http://www.davsclaus.com/2012/02/correlating-logs-from-redelivered.html

On Fri, Apr 26, 2013 at 1:01 PM, leroykendall <le...@yahoo.com> wrote:
> Hi Claus,
>
> Yes, you are right about exhausted.
> I recognized that when got that code working as expected with redelivery.
>
> Just in case if this could be helpful for someone other let me write down
> changes I've made to above code.
>
> 1. Moved  Camel's JMS component configuration to separate bean with added
> cache level (CACHE_CONSUMER):
>
>     <bean id="camelJmsComponent"
> class="org.apache.camel.component.jms.JmsComponent">
>         <property name="configuration" ref="jmsConfig"/>
>     </bean>
>
>     <bean id="jmsConfig"
> class="org.apache.camel.component.jms.JmsConfiguration">
>         <property name="connectionFactory" ref="jmsConnectionFactory" />
>         <property name="transacted" value="true" />
>         <property name="transactionManager" ref="jmsTransactionManager" />
>         <property name="cacheLevelName" value="CACHE_CONSUMER" />
>     </bean>
>
> 2. Added maxConnections property to the JMS pooled connection factory (with
> value 8).
>
> Now the code works excellent with redelivery.
>
> Thanks.
> --Victor
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/JMS-transaction-behavior-inside-of-route-tp5730513p5731608.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
FuseSource is now part of Red Hat
Email: cibsen@redhat.com
Web: http://fusesource.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: JMS transaction behavior inside of route

Posted by leroykendall <le...@yahoo.com>.
Hi Claus,

Yes, you are right about exhausted.
I recognized that when got that code working as expected with redelivery.

Just in case if this could be helpful for someone other let me write down
changes I've made to above code.

1. Moved  Camel's JMS component configuration to separate bean with added
cache level (CACHE_CONSUMER):

    <bean id="camelJmsComponent"
class="org.apache.camel.component.jms.JmsComponent">
        <property name="configuration" ref="jmsConfig"/>
    </bean>

    <bean id="jmsConfig"
class="org.apache.camel.component.jms.JmsConfiguration">
        <property name="connectionFactory" ref="jmsConnectionFactory" />
        <property name="transacted" value="true" />
        <property name="transactionManager" ref="jmsTransactionManager" />
        <property name="cacheLevelName" value="CACHE_CONSUMER" />
    </bean>

2. Added maxConnections property to the JMS pooled connection factory (with
value 8).

Now the code works excellent with redelivery.

Thanks.
--Victor



--
View this message in context: http://camel.465427.n5.nabble.com/JMS-transaction-behavior-inside-of-route-tp5730513p5731608.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JMS transaction behavior inside of route

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Its the message broker that does the external redelivery. Camel
doesn't do it. Camel just log that there was an exception thrown
during routing, and its regarded as exhausted after the very first
delivery attempt (eg no redelivery).

So that triggers a rollback on the TX, which the TX manager handles,
and the message broker, will then know that the message failed, and it
can react according to its redelivery settings.




On Thu, Apr 25, 2013 at 11:01 PM, leroykendall <le...@yahoo.com> wrote:
> Hi Claus,
>
> Thank you for the link to the great page.
> One issue that I've stuck is how to perform JMS redelivery in Camel using
> Spring orchestrated transactions.
> My spring context is:
>
>     <bean id="camelJmsComponent"
> class="org.apache.camel.component.jms.JmsComponent">
>         <property name="transacted" value="true"/>
>         <property name="transactionManager" ref="jmsTransactionManager"/>
>         <property name="concurrentConsumers" value="1"/>
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsTransactionManager"
> class="org.springframework.jms.connection.JmsTransactionManager">
>         <property name="connectionFactory" ref="jmsConnectionFactory"/>
>     </bean>
>
>     <bean id="jmsConnectionFactory"
> class="org.apache.activemq.pool.PooledConnectionFactory">
>         <property name="connectionFactory" ref="amqConnectionFactory"/>
>     </bean>
>
>     <bean id="amqConnectionFactory"
> class="org.apache.activemq.ActiveMQConnectionFactory">
>         <property name="brokerURL" value="tcp://localhost:3303"/>
>         <property name="redeliveryPolicy" ref="amqRedeliveryPolicy"/>
>     </bean>
>
>     <bean id="amqRedeliveryPolicy"
> class="org.apache.activemq.RedeliveryPolicy">
>         <property name="useExponentialBackOff" value="true"/>
>         <property name="backOffMultiplier" value="2"/>
>         <property name="initialRedeliveryDelay" value="1000"/>
>         <property name="maximumRedeliveries" value="5"/>
>     </bean>
>
>     <bean id="PROPAGATION_REQUIRED"
>           class="org.apache.camel.spring.spi.SpringTransactionPolicy">
>         <property name="transactionManager" ref="jmsTransactionManager"/>
>     </bean>
>
>     <bean id="illegalArgumentException"
> class="java.lang.IllegalArgumentException"/>
>
>     <bean id="handlerBean" class="com.playtech.ums.tests.JmsHandlerBean"/>
>
>     <camel:camelContext>
>
>         <camel:route>
>             <camel:from uri="jms:queue:test.lab.queue"/>
>             <camel:transacted ref="PROPAGATION_REQUIRED"/>
>             <camel:log message="Redelivered: ${header.JMSRedelivered}"/>
>             <camel:choice>
>                 <camel:when>
>                     <camel:simple>${in.body} contains
> 'exception'</camel:simple>
>                     <camel:log message="Incoming message contains
> 'exception': ${in.body}" loggingLevel="WARN"/>
>                     <camel:throwException ref="illegalArgumentException"/>
>                 </camel:when>
>             </camel:choice>
>             <camel:to uri="handlerBean"/>
>         </camel:route>
>
>     </camel:camelContext>
>
> When I executed this code I've got message "Exhausted after delivery
> attempt: 1" instead of "exponential back off" redelivery.
> Could you please help?
>
> Thanks.
> --Victor
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/JMS-transaction-behavior-inside-of-route-tp5730513p5731566.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
FuseSource is now part of Red Hat
Email: cibsen@redhat.com
Web: http://fusesource.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen

Re: JMS transaction behavior inside of route

Posted by leroykendall <le...@yahoo.com>.
Hi Claus,

Thank you for the link to the great page.
One issue that I've stuck is how to perform JMS redelivery in Camel using
Spring orchestrated transactions.
My spring context is:

    <bean id="camelJmsComponent"
class="org.apache.camel.component.jms.JmsComponent">
        <property name="transacted" value="true"/>
        <property name="transactionManager" ref="jmsTransactionManager"/>
        <property name="concurrentConsumers" value="1"/>
        <property name="connectionFactory" ref="jmsConnectionFactory"/>
    </bean>

    <bean id="jmsTransactionManager"
class="org.springframework.jms.connection.JmsTransactionManager">
        <property name="connectionFactory" ref="jmsConnectionFactory"/>
    </bean>

    <bean id="jmsConnectionFactory"
class="org.apache.activemq.pool.PooledConnectionFactory">
        <property name="connectionFactory" ref="amqConnectionFactory"/>
    </bean>

    <bean id="amqConnectionFactory"
class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" value="tcp://localhost:3303"/>
        <property name="redeliveryPolicy" ref="amqRedeliveryPolicy"/>
    </bean>

    <bean id="amqRedeliveryPolicy"
class="org.apache.activemq.RedeliveryPolicy">
        <property name="useExponentialBackOff" value="true"/>
        <property name="backOffMultiplier" value="2"/>
        <property name="initialRedeliveryDelay" value="1000"/>
        <property name="maximumRedeliveries" value="5"/>
    </bean>

    <bean id="PROPAGATION_REQUIRED"
          class="org.apache.camel.spring.spi.SpringTransactionPolicy">
        <property name="transactionManager" ref="jmsTransactionManager"/>
    </bean>

    <bean id="illegalArgumentException"
class="java.lang.IllegalArgumentException"/>

    <bean id="handlerBean" class="com.playtech.ums.tests.JmsHandlerBean"/>

    <camel:camelContext>

        <camel:route>
            <camel:from uri="jms:queue:test.lab.queue"/>
            <camel:transacted ref="PROPAGATION_REQUIRED"/>
            <camel:log message="Redelivered: ${header.JMSRedelivered}"/>
            <camel:choice>
                <camel:when>
                    <camel:simple>${in.body} contains
'exception'</camel:simple>
                    <camel:log message="Incoming message contains
'exception': ${in.body}" loggingLevel="WARN"/>
                    <camel:throwException ref="illegalArgumentException"/>
                </camel:when>
            </camel:choice>
            <camel:to uri="handlerBean"/>
        </camel:route>

    </camel:camelContext>

When I executed this code I've got message "Exhausted after delivery
attempt: 1" instead of "exponential back off" redelivery.
Could you please help?

Thanks.
--Victor



--
View this message in context: http://camel.465427.n5.nabble.com/JMS-transaction-behavior-inside-of-route-tp5730513p5731566.html
Sent from the Camel - Users mailing list archive at Nabble.com.

Re: JMS transaction behavior inside of route

Posted by Claus Ibsen <cl...@gmail.com>.
Hi

Take a look at the transactional client eip
http://camel.apache.org/transactional-client.html


On Mon, Apr 8, 2013 at 5:03 PM, leroykendall <le...@yahoo.com> wrote:
> Hi,
>
> The standard JMS transaction looks like:
>
>     session = connection.createSession( true, -1 );
>     queue = session.createQueue( "queue.name" );
>     consumer = session.createConsumer( queue );
>
>     // Messages processing loop
>     try {
>         message = consumer.receive();       // Receive message from queue
>         ...
>         messageFlow( message );
>         anotherMessageFlow( message );
>         ...
>         session.commit();          // Message acknowledge
>     } catch (Exception ex) {
>         session.rollback();         // Put message back to queue for
> redelivery
>     }
>
> Question: can we do similar behavior in Camel route?
> So it would look like:
>
>     <route>
>         <from uri="jms:queue:queue.name"/>    <|-- Receive message from
> queue, but don't do acknowledge yet. -->
>         ...
>         <bean ref="messageFlow"/>
>         <bean ref="anotherMessageFlow"/>     <|-- If exception is thrown
> here then do rollback of message back to JMS queue for redelivery. -->
>     </route>                                            <|-- End of route.
> Do JMS session commit and message acknowledge. -->
>
> So can Camel 2.10.0 do this?
>
> Thanks.
> --Victor
>
>
>
> --
> View this message in context: http://camel.465427.n5.nabble.com/JMS-transaction-behavior-inside-of-route-tp5730513.html
> Sent from the Camel - Users mailing list archive at Nabble.com.



-- 
Claus Ibsen
-----------------
Red Hat, Inc.
FuseSource is now part of Red Hat
Email: cibsen@redhat.com
Web: http://fusesource.com
Twitter: davsclaus
Blog: http://davsclaus.com
Author of Camel in Action: http://www.manning.com/ibsen