XA support and JMS in Apache Camel - 7.0

Talend ESB Container Administration Guide

EnrichVersion
7.0
EnrichProdName
Talend Data Fabric
Talend Data Services Platform
Talend ESB
Talend MDM Platform
Talend Open Studio for ESB
Talend Real-Time Big Data Platform
task
Administration and Monitoring
Design and Development
Installation and Upgrade
EnrichPlatform
Talend ESB

It is also possible to use transactions in Apache Camel routes. Camel relies in the spring transaction abstraction so it is necessary to use the right wrapper class to make JTA transactions work.

A transactional route can look like this:

from("jms:queue1").transactional().to("jms:queue2")

The transactional() DSl Element tells Karaf to start a transaction when the route enters the segment and commit once the route is completed successfully. In case of unhandled errors, it will roll back.

The above approach would not cover the part through where the message is received. So to make the whole route transactional, it is necessary to also configure the JMS component to do JTA transactions.

For this to work like in databases, you first need to provide a ConnectionFactory as an OSGi service that is correctly wrapped for XA and pooling.

The ConnectionFactory and the TransactionManager are referenced as OSGi services. They then need to be injected into the JMSComponent and the SpringTransactionPolicy.

<reference id="connectionFactory" interface="javax.jms.ConnectionFactory"/>
<reference id="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager"/>

<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
    <property name="connectionFactory" ref="connectionFactory"/>
    <property name="transactionManager" ref="transactionManager"/>
</bean>

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

With this set-up, the JmsComponent will always receive messages inside a JTA transaction and will also participate in a JTA transaction when sending out messages.

Interestingly, the transaction manager is looked up as spring PlatformTransactionManager. This is possible as the default transaction manager in Karaf from Aries already implements this interface in addition to the plain JTA TransactionManager.