We are building an application using ServiceMix (CXF, Camel, Karaf...) and we've run into an issue with transactions not propagating to camel routes as we'd like them to. We have several OSGI components that run under transactions using the Aries transaction management like the following:
<bean id="serviceBean" class="<class>"> <property name="dataSource" ref="ds"/> <property name="camelContext" ref="camelCtx"/> <tx:transaction method="updateAddress, createAddress, deleteAddress" value="Required" /> <tx:transaction method="getAddress, findAddresses" value="Supports" /> </bean> We have published a DataSource which is transaction aware for our components to use. It shows up in SMX as the following: aries.xa.aware = true dsName = ds objectClass = javax.sql.DataSource service.id = 298 In our components we are able to perform database transactions that successfully get committed/rolled back as expected without having to manually enlist the JDBC connection. It works great. Those same components also will send various JMS messages as they succeed/fail. Our goal is that if a component sends a JMS message on success and later rolls back the JMS message would be retracted. If we lookup a JMS ConnectionFactory, create a connection, session, manually enlist the session into the current transaction and send the message all in code it actually works as desired. What we hope to be able to do however is to remove the code and use camel instead to process the message and pass it along to the JMS topic, in the same transaction that the OSGI component is running in but we can't quite get it to work. Below is our latest configuration and code and at this point the message posts to the topic but never rolls back. Blueprint File <bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent"> <property name="connectionFactory" ref="jmsXaConnectionFactory"/> <property name="transacted" value="true"/> <property name="transactionManager" ref="jmsTransactionManager"/> </bean> <bean id="mandatory" class="org.apache.camel.spring.spi.SpringTransactionPolicy"> <property name="transactionManager" ref="jmsTransactionManager"/> <property name="propagationBehaviorName" value="PROPAGATION_MANDATORY"/> </bean> <bean id="jmsXaConnectionFactory" class="org.apache.activemq.ActiveMQXAConnectionFactory"> <property name="brokerURL" value="tcp://localhost:61616"/> </bean> <reference id="jmsTransactionManager" interface="org.springframework.transaction.PlatformTransactionManager"/> <camel:camelContext id="camelCtx" trace="true"> <camel:route> <camel:from uri="direct:genEvent"/> <camel:wireTap uri="direct:wireTap"/> <camel:transacted ref="mandatory"/> <camel:to uri="activemq:topic:event-notifications"/> </camel:route> <camel:route> <camel:from uri="direct:wireTap"/> <camel:to uri="log:logger?showAll=true"/> </camel:route> </camel:camelContext> Code: ProducerTemplate pt = camelCtx.createProducerTemplate(); Map<String, Object> headers = new HashMap<String, Object>(); headers.put("EventType", eventType); headers.put("ClientID", 0); headers.put("EntityType", "Address"); pt.sendBodyAndHeaders("direct:genEvent", getAddress(addressID), headers); Like I mentioned, the code all works in the success case but doesn't rollback the JMS message in the failure case. Apparently the transaction context isn't being passed on to the camel route even though it's using the same transaction manager under the covers. Is that by design or is there a way to make this scenario work? We'd really like to be able use the camel route approach so we can do more complex things than what I show here. Thanks, Chris