Thanks Raul, that issue does look like the problem I'm seeing on the success case. I'll try and upgrade to 5.6-SNAPSHOT tomorrow and see if that resolves the issue.
I now see that I need to have a XA Connection Factory and XA Connection Pool for Camel to be able to integrate with a XA transaction. What I don't understand is why I'm able to, in code, take a connection from a normal connection factory/pool, that is configured with a transaction manager and has a ResourceManager associated with it, and enlist it in a XA transaction but that same setup won't work with Camel. I'm sure there is a good reason, I just don't understand why. Any thoughts? Here is my normal ActiveMQ setup that works with XA transactions from code. <bean id="activemqConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory"> <property name="brokerURL" value="vm://default?create=false&waitForStart=10000" /> </bean> <bean id="pooledConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"> <property name="maxConnections" value="8" /> <property name="connectionFactory" ref="activemqConnectionFactory" /> </bean> <bean id="resourceManager" class="org.apache.activemq.pool.ActiveMQResourceManager" init-method="recoverResource"> <property name="transactionManager" ref="transactionManager" /> <property name="connectionFactory" ref="activemqConnectionFactory" /> <property name="resourceName" value="activemq.default" /> </bean> <reference id="transactionManager" interface="javax.transaction.TransactionManager" /> <service ref="pooledConnectionFactory" interface="javax.jms.ConnectionFactory"> <service-properties> <entry key="name" value="localhost"/> </service-properties> </service> Thanks again for helping me out, I appreciate it, Chris On Tue, Apr 17, 2012 at 4:36 PM, Raul Kripalani <r...@fusesource.com> wrote: > Also, see https://issues.apache.org/jira/browse/AMQ-3251. > > I think the fix was backported to a release of Fuse ESB 4.4.1, that's > why we don't experience it in the example. > > You may want to try with a Fuse ESB release if using an AMQ snapshot > is not an option for you. > > Regards, > Raul. > > On 18 Apr 2012, at 00:28, Raul Kripalani <r...@fusesource.com> wrote: > > > I noticed you are using PROPAGATION_MANDATORY, which will throw an > > exception if a transaction doesn't already exist. Could that justify > > the exception you see when isolating only Camel? Can you try with > > PROPAGATION_REQUIRED instead? > > > > The sample I pointed you to works with no changes. In fact, you may > > want to try it out locally substituting the DB interactions with > > another JMS send... > > > > Thanks. > > > > On 17 Apr 2012, at 22:21, Chris Geer <ch...@cxtsoftware.com> wrote: > > > >> The only place I'm not using an already XA aware connection factory is > in > >> the API side, which is working perfectly because I'm manually enlisting > the > >> Session. > >> > >> On the camel side, I used your example exactly as you can see in my > >> blueprint file and everything depends on XA aware activemq objects. > Just to > >> make sure the API side of things wasn't interfering with the camel part > >> (which would be odd), I commented out all the code except for the camel > >> send and commented out the reference to the standard JMS Connection > >> Factory. Even with those drastic measures, I still got all the same > errors > >> even though the camel route was the only participant in the transaction > >> along with the OSGI component itself. > >> > >> What was the change you made to get it working without errors? > >> > >> Chris > >> > >> On Tue, Apr 17, 2012 at 1:48 PM, Raul Kripalani <r...@fusesource.com> > wrote: > >> > >>> It looks like you may not be using an XA-aware Pooled Connection > Factory :D > >>> > >>> See > >>> > http://activemq.apache.org/maven/5.5.0/activemq-pool/apidocs/org/apache/activemq/pool/XaPooledConnectionFactory.html > >>> > >>> It may look catchy, but all the layers of the stack need to be > >>> XA-aware, as XA requires a different behaviour when handling borrowing > >>> and returning to the pool. > >>> > >>> Let me know if it works for you. > >>> > >>> Regards, > >>> Raul. > >>> > >>> On 17 Apr 2012, at 18:31, Chris Geer <ch...@cxtsoftware.com> wrote: > >>> > >>>> Raul, > >>>> > >>>> Thanks for the information. I tried what you said and I think it did > have > >>>> some success with rolling back the transaction but it causes > significant > >>>> errors to be thrown during a success case. As I've written a sample to > >>>> debug this issue I wanted you to have my latest code so we can be > >>>> referencing the same thing if you're willing to take another look. > >>>> > >>>> README: http://pastebin.com/UWq3yk4c > >>>> OSGI Implementation: http://pastebin.com/ifQTybn3 > >>>> OSGI Interface: http://pastebin.com/zEUP8jJJ > >>>> Blueprint File: http://pastebin.com/sxBtxNCq > >>>> Test Driver/Logger: http://pastebin.com/SDVFvjGm > >>>> pom.xml: http://pastebin.com/kTXXaebV > >>>> > >>>> Part of the error I'm seeing is this (commit -> rollback) > >>>> > >>>> 10:12:52,624 | WARN | 52 - timer://foo | PooledSession > >>>> | 57 - org.apache.activemq.activemq-pool - 5.5.1 | Caught exception > >>> trying > >>>> rollback() when putting session back into the pool: > >>>> javax.jms.TransactionInProgressException: Cannot rollback() inside an > >>>> XASession > >>>> javax.jms.TransactionInProgressException: Cannot rollback() inside an > >>>> XASession > >>>> at > >>>> > >>> > org.apache.activemq.ActiveMQXASession.rollback(ActiveMQXASession.java:76)[60:org.apache.activemq.activemq-core:5.5.1] > >>>> at > >>>> > >>> > org.apache.activemq.pool.PooledSession.close(PooledSession.java:111)[57:org.apache.activemq.activemq-pool:5.5.1] > >>>> at > >>>> > >>> > org.apache.activemq.pool.XaConnectionPool$Synchronization.afterCompletion(XaConnectionPool.java:90)[57:org.apache.activemq.activemq-pool:5.5.1] > >>>> at > >>>> > >>> > org.apache.geronimo.transaction.manager.TransactionImpl.afterCompletion(TransactionImpl.java:540)[45:org.apache.aries.transaction.manager:0.3.0] > >>>> at > >>>> > >>> > org.apache.geronimo.transaction.manager.TransactionImpl.afterCompletion(TransactionImpl.java:533)[45:org.apache.aries.transaction.manager:0.3.0] > >>>> at > >>>> > >>> > org.apache.geronimo.transaction.manager.TransactionImpl.commit(TransactionImpl.java:329)[45:org.apache.aries.transaction.manager:0.3.0] > >>>> at > >>>> > >>> > org.apache.geronimo.transaction.manager.TransactionManagerImpl.commit(TransactionManagerImpl.java:252)[45:org.apache.aries.transaction.manager:0.3.0] > >>>> > >>>> > >>>> Chris > >>>> > >>>> On Tue, Apr 17, 2012 at 9:44 AM, Raul Kripalani <r...@fusesource.com> > >>> wrote: > >>>> > >>>>> I noticed several things in your config. > >>>>> > >>>>> 1) the JMS config should be inside the 'configuration' property of > the > >>>>> ActiveMQComponent: > >>>>> > >>>>> <!-- ActiveMQ JMS Configuration is defined as Transacted and > leverages > >>> XA > >>>>> Transactions --> > >>>>> <bean id="activemq" > >>>>> class="org.apache.activemq.camel.component.ActiveMQComponent"> > >>>>> <property name="configuration"> > >>>>> <bean class="org.apache.camel.component.jms.JmsConfiguration"> > >>>>> <property name="connectionFactory" > >>>>> ref="pooledConnectionFactoryXa"/> > >>>>> <property name="transactionManager" ref="platformTxManager" /> > >>>>> <property name="transacted" value="false"/> > >>>>> <property name="cacheLevelName" value="CACHE_NONE"/> > >>>>> </bean> > >>>>> </property> > >>>>> </bean> > >>>>> > >>>>> 2) the 'transacted' property should be false as above, because you > don't > >>>>> want the component to manage the transactions locally. The enrolment > of > >>>>> resources and coordination of transaction will happen on the XA > level. > >>>>> > >>>>> 3) you are missing the ActiveMQResourceManager, which needs an > >>> injection of > >>>>> a javax.transaction.TransactionManager, which in reality is the same > as > >>> the > >>>>> PlatformTransactionManager, but you under a different interface > >>>>> > >>>>> See the following link for how your config should look like: > >>>>> > >>>>> > >>> > https://github.com/FuseByExample/camel-persistence-part2/blob/master/route-one-tx-manager/src/main/resources/META-INF/spring/springConfig.xml > >>>>> . > >>>>> > >>>>> And of course, the route must be invoked from the same thread where > the > >>>>> transaction is being started, and you cannot use the SEDA component > for > >>>>> that. You must invoke it via a direct endpoint and I think > >>>>> requestBodyAndHeader(), but I'm not sure about this last point. > >>>>> > >>>>> Regards, > >>>>> > >>>>> *Raúl Kripalani* > >>>>> Principal Consultant | FuseSource Corp. > >>>>> r...@fusesource.com | fusesource.com <http://www.fusesource.com/> > >>> skype: > >>>>> raul.fuse | twitter: @raulvk <http://twitter.com/raulvk>, > >>>>> @fusenews<http://twitter.com/fusenews> > >>>>> > >>>>> <http://twitter.com/fusenews> > >>>>> > >>>>> On 17 April 2012 16:53, Chris Geer <ch...@cxtsoftware.com> wrote: > >>>>> > >>>>>> Raul, > >>>>>> > >>>>>> I gave that a shot but it actually made the problem worse. > >>>>>> ProducerTemplate.requestBodyAndHeader uses an InOut exchange pattern > >>> but > >>>>>> since I'm not sending responses it always fails (regardless of > >>>>> transaction) > >>>>>> with a timeout saying it didn't get a response. It also send the > >>> message > >>>>> to > >>>>>> the topic even without the transaction being committed so it > wouldn't > >>>>> solve > >>>>>> the transaction problem anyway. > >>>>>> > >>>>>> Chris > >>>>>> > >>>>>> On Tue, Apr 17, 2012 at 1:47 AM, Raul Kripalani < > r...@fusesource.com> > >>>>>> wrote: > >>>>>> > >>>>>>> Hi Chris! > >>>>>>> > >>>>>>> Transaction Managers bind transactions to threads, and a possible > >>> cause > >>>>>> for > >>>>>>> your transaction getting lost is that your route is being called > >>>>>>> asynchronously from another thread. > >>>>>>> > >>>>>>> This is because you are using ProducerTemplate.send...(). > >>>>>>> > >>>>>>> Can you replace this with > ProducerTemplate.requestBodyAndHeader(...), > >>>>>> which > >>>>>>> in theory should call the route synchronously in the same thread? > >>>>>>> > >>>>>>> Regards, > >>>>>>> > >>>>>>> *Raúl Kripalani* > >>>>>>> Principal Consultant | FuseSource Corp. > >>>>>>> r...@fusesource.com | fusesource.com <http://www.fusesource.com/> > >>>>> skype: > >>>>>>> raul.fuse | twitter: @raulvk <http://twitter.com/raulvk>, > >>>>>>> @fusenews<http://twitter.com/fusenews> > >>>>>>> > >>>>>>> <http://twitter.com/fusenews> > >>>>>>> > >>>>>>> On 16 April 2012 23:09, Chris Geer <ch...@cxtsoftware.com> wrote: > >>>>>>> > >>>>>>>> Claus, > >>>>>>>> > >>>>>>>> I'm still struggling with this so I've put together a quick sample > >>>>>>> project > >>>>>>>> that shows the problem. It consists of an OSGI component that runs > >>>>>> under > >>>>>>> a > >>>>>>>> transaction and posts two JMS messages (one with Camel and one > with > >>>>> JMS > >>>>>>>> APIs) then rolls back the transactions. I would hope to see both > >>>>>> messages > >>>>>>>> not be delivered but instead what I see if the one sent via camel > >>>>> being > >>>>>>>> delivered while the other one is rolled back. I'm sure I'm > probably > >>>>>> doing > >>>>>>>> something wrong but I can't figure it out. > >>>>>>>> > >>>>>>>> Is there a place I can post my sample project where someone might > be > >>>>>> able > >>>>>>>> to give it a quick look? > >>>>>>>> > >>>>>>>> Thanks, > >>>>>>>> Chris > >>>>>>>> > >>>>>>>> On Sat, Apr 7, 2012 at 3:19 AM, Claus Ibsen < > claus.ib...@gmail.com> > >>>>>>> wrote: > >>>>>>>> > >>>>>>>>> On Thu, Apr 5, 2012 at 5:57 PM, Chris Geer < > ch...@cxtsoftware.com> > >>>>>>>> wrote: > >>>>>>>>>> Claus, > >>>>>>>>>> > >>>>>>>>>> I realize that but I can't explain what I'm seeing. Here is an > >>>>>>>> additional > >>>>>>>>>> piece of info, here is debug log for the sending of the message. > >>>>> As > >>>>>>> you > >>>>>>>>> can > >>>>>>>>>> see, the transaction fields are all null but I don't know if > that > >>>>>> is > >>>>>>>>> normal > >>>>>>>>>> or a symptom of the problem. > >>>>>>>>>> > >>>>>>>>>> 08:51:22,906 | DEBUG | erations/address | JmsConfiguration > >>>>>>>>>> | 169 - org.apache.camel.camel-jms - 2.9.2.SNAPSHOT | Sending > JMS > >>>>>>>> message > >>>>>>>>>> to: topic://event-notifications with message: > >>>>> ActiveMQBytesMessage > >>>>>>>>>> {commandId = 0, responseRequired = false, messageId = null, > >>>>>>>>>> originalDestination = null, originalTransactionId = null, > >>>>>> producerId > >>>>>>> = > >>>>>>>>>> null, destination = null, transactionId = null, expiration = 0, > >>>>>>>>> timestamp = > >>>>>>>>>> 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, > >>>>> correlationId > >>>>>> = > >>>>>>>>> null, > >>>>>>>>>> replyTo = null, persistent = true, type = null, priority = 0, > >>>>>>> groupID = > >>>>>>>>>> null, groupSequence = 0, targetConsumerId = null, compressed = > >>>>>> false, > >>>>>>>>>> userID = null, content = null, marshalledProperties = null, > >>>>>>>>> dataStructure = > >>>>>>>>>> null, redeliveryCounter = 0, size = 0, properties = > >>>>>>>> {EntityType=Address, > >>>>>>>>>> breadcrumbId=ID-CXTMBP-Chris-local-62052-1333577461603-22-3, > >>>>>>>>>> EventType=EntityCreated, ClientID=0}, readOnlyProperties = > false, > >>>>>>>>>> readOnlyBody = false, droppable = false} ActiveMQBytesMessage{ > >>>>>>>> bytesOut = > >>>>>>>>>> org.apache.activemq.util.ByteArrayOutputStream@51762faf, > >>>>> dataOut = > >>>>>>>>>> java.io.DataOutputStream@2634b3f1, dataIn = null } > >>>>>>>>>> > >>>>>>>>> > >>>>>>>>> I would only suspect transaction ids being populated in the AMQ > >>>>>>>>> message if the message originated from the AMQ broker. Creating a > >>>>> new > >>>>>>>>> message to be send would most likely not populate TX ids and > >>>>> whatnot. > >>>>>>>>> But the work is still carried out under the TX manager. (if TX is > >>>>>>>>> properly configured and working - yeah thats the hard part). > >>>>>>>>> > >>>>>>>>>> Here is more of the stack trace that shows the transaction being > >>>>>>>>> committed > >>>>>>>>>> for some reason. > >>>>>>>>>> > >>>>>>>>>> 08:51:22,888 | DEBUG | erations/address | > TransactionErrorHandler > >>>>>>>>>> | 166 - org.apache.camel.camel-core - 2.9.2.SNAPSHOT | > >>>>> Transaction > >>>>>>>> begin > >>>>>>>>>> (0x1f2198ab) redelivered(unknown) for (MessageId: > >>>>>>>>>> ID-CXTMBP-Chris-local-62052-1333577461603-22-3 on ExchangeId: > >>>>>>>>>> ID-CXTMBP-Chris-local-62052-1333577461603-22-4)) > >>>>>>>>>> 08:51:22,888 | DEBUG | erations/address | JtaTransactionManager > >>>>>>>>>> | 139 - org.springframework.transaction - 3.0.6.RELEASE | > >>>>>>>> Participating > >>>>>>>>> in > >>>>>>>>>> existing transaction > >>>>>>>>>> 08:51:22,906 | DEBUG | erations/address | JmsConfiguration > >>>>>>>>>> | 169 - org.apache.camel.camel-jms - 2.9.2.SNAPSHOT | Sending > JMS > >>>>>>>> message > >>>>>>>>>> to: topic://event-notifications with message: > >>>>> ActiveMQBytesMessage > >>>>>>>>>> {commandId = 0, responseRequired = false, messageId = null, > >>>>>>>>>> originalDestination = null, originalTransactionId = null, > >>>>>> producerId > >>>>>>> = > >>>>>>>>>> null, destination = null, transactionId = null, expiration = 0, > >>>>>>>>> timestamp = > >>>>>>>>>> 0, arrival = 0, brokerInTime = 0, brokerOutTime = 0, > >>>>> correlationId > >>>>>> = > >>>>>>>>> null, > >>>>>>>>>> replyTo = null, persistent = true, type = null, priority = 0, > >>>>>>> groupID = > >>>>>>>>>> null, groupSequence = 0, targetConsumerId = null, compressed = > >>>>>> false, > >>>>>>>>>> userID = null, content = null, marshalledProperties = null, > >>>>>>>>> dataStructure = > >>>>>>>>>> null, redeliveryCounter = 0, size = 0, properties = > >>>>>>>> {EntityType=Address, > >>>>>>>>>> breadcrumbId=ID-CXTMBP-Chris-local-62052-1333577461603-22-3, > >>>>>>>>>> EventType=EntityCreated, ClientID=0}, readOnlyProperties = > false, > >>>>>>>>>> readOnlyBody = false, droppable = false} ActiveMQBytesMessage{ > >>>>>>>> bytesOut = > >>>>>>>>>> org.apache.activemq.util.ByteArrayOutputStream@51762faf, > >>>>> dataOut = > >>>>>>>>>> java.io.DataOutputStream@2634b3f1, dataIn = null } > >>>>>>>>>> 08:51:22,907 | DEBUG | erations/address | JtaTransactionManager > >>>>>>>>>> | 139 - org.springframework.transaction - 3.0.6.RELEASE | > >>>>>>> Registering > >>>>>>>>>> after-completion synchronization with existing JTA transaction > >>>>>>>>>> 08:51:22,907 | DEBUG | erations/address | > TransactionErrorHandler > >>>>>>>>>> | 166 - org.apache.camel.camel-core - 2.9.2.SNAPSHOT | > >>>>> Transaction > >>>>>>>>> commit > >>>>>>>>>> (0x1f2198ab) redelivered(unknown) for (MessageId: > >>>>>>>>>> ID-CXTMBP-Chris-local-62052-1333577461603-22-3 on ExchangeId: > >>>>>>>>>> ID-CXTMBP-Chris-local-62052-1333577461603-22-4)) > >>>>>>>>>> > >>>>>>>>> > >>>>>>>>> That last debug logging is just Camel saying that the TX > completed > >>>>>>>>> successfully (in that leg). Its up to the TX manager when > actually > >>>>> to > >>>>>>>>> commit the TX. If a TX was started outside, then the commit is > >>>>>>>>> executed at that point. > >>>>>>>>> > >>>>>>>>> So this is normal. > >>>>>>>>> > >>>>>>>>>> On Thu, Apr 5, 2012 at 8:19 AM, Claus Ibsen < > >>>>> claus.ib...@gmail.com > >>>>>>> > >>>>>>>>> wrote: > >>>>>>>>>> > >>>>>>>>>>> On Thu, Apr 5, 2012 at 4:59 PM, Chris Geer < > >>>>> ch...@cxtsoftware.com > >>>>>>> > >>>>>>>>> wrote: > >>>>>>>>>>>> Christian, > >>>>>>>>>>>> > >>>>>>>>>>>> I have that book and that is what I used for a lot of my > >>>>>>> reference. > >>>>>>>> In > >>>>>>>>>>>> fact, they only major difference between his source and mine > >>>>> is > >>>>>> he > >>>>>>>> is > >>>>>>>>>>> using > >>>>>>>>>>>> Atomikos as the transaction manager and I'm using aries. I am > >>>>>>>>> referencing > >>>>>>>>>>>> an existing PlatformTransactionManager instead of creating a > >>>>>>>>>>>> JtaTransactionManager but PlatformTransactionManager > >>>>> implements > >>>>>>>>>>>> JtaTransactionManager so it should be ok. > >>>>>>>>>>>> > >>>>>>>>>>>> As for the datasource, I'm actually publishing it from another > >>>>>>> OSGI > >>>>>>>>>>>> component as a service so it can be reused. I'm creating it in > >>>>>>> code > >>>>>>>>> right > >>>>>>>>>>>> now as defined below. > >>>>>>>>>>>> > >>>>>>>>>>>> BasicManagedDataSource ds = new > >>>>> BasicManagedDataSource(); > >>>>>>>>>>>> > >>>>>>>>>>>> if(xaDataSourceClass != null && > >>>>>>>> !xaDataSourceClass.isEmpty()) { > >>>>>>>>>>>> try { > >>>>>>>>>>>> XADataSource dsi = > >>>>>>>>>>>> (XADataSource)Class.forName(xaDataSourceClass).newInstance(); > >>>>>>>>>>>> Method setUrl = > >>>>>> dsi.getClass().getMethod("setUrl", > >>>>>>>> new > >>>>>>>>>>>> Class[] {String.class}); > >>>>>>>>>>>> setUrl.invoke(dsi, (String) > >>>>>>> config.get(CONNSTR_KEY)); > >>>>>>>>>>>> ds.setXADataSource(xaDataSourceClass); > >>>>>>>>>>>> ds.setXaDataSourceInstance(dsi); > >>>>>>>>>>>> } catch (IllegalArgumentException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Couldn't create instance", ex); > >>>>>>>>>>>> } catch (InvocationTargetException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Couldn't create instance", ex); > >>>>>>>>>>>> } catch (NoSuchMethodException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Couldn't create instance", ex); > >>>>>>>>>>>> } catch (SecurityException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Couldn't create instance", ex); > >>>>>>>>>>>> } catch (InstantiationException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Couldn't create instance", ex); > >>>>>>>>>>>> } catch (IllegalAccessException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Couldn't create instance", ex); > >>>>>>>>>>>> } catch (ClassNotFoundException ex) { > >>>>>>>>>>>> throw new > >>>>>>> ConfigurationException("xaDataSourceClass", > >>>>>>>>>>>> "Class not found", ex); > >>>>>>>>>>>> } > >>>>>>>>>>>> } else { > >>>>>>>>>>>> ds.setDriverClassName((String) > >>>>>> config.get(DRIVER_KEY)); > >>>>>>>>>>>> ds.setUrl((String) config.get(CONNSTR_KEY)); > >>>>>>>>>>>> } > >>>>>>>>>>>> > >>>>>>>>>>>> BundleContext context = > >>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>> > FrameworkUtil.getBundle(BedrockConnectionPoolFactory.class).getBundleContext(); > >>>>>>>>>>>> > >>>>>>>>>>>> ds.setTransactionManager(transMgr); > >>>>>>>>>>>> > >>>>>>>>>>>> Hashtable<String, String> sp = new Hashtable<String, > >>>>>>>> String>(); > >>>>>>>>>>>> sp.put(DSNAME_KEY, (String) config.get(DSNAME_KEY)); > >>>>>>>>>>>> ServiceRegistration reg = > >>>>>>>>>>>> context.registerService("javax.sql.XADataSource", > >>>>>>>>>>>> ds.getXaDataSourceInstance(), sp); > >>>>>>>>>>>> regMap.put(id, reg); > >>>>>>>>>>>> > >>>>>>>>>>>> The transMgr variable above is looking up the Aries > >>>>> transaction > >>>>>>>>> manager > >>>>>>>>>>>> deployed in SMX (same one my JMS code is getting through the > >>>>>>>>>>>> PlatformTransactionManager interface). > >>>>>>>>>>>> > >>>>>>>>>>>> The biggest challenge I've had is that every single camel > >>>>>>>> transaction > >>>>>>>>>>>> example I've seen starts the transaction INSIDE camel. They > >>>>> all > >>>>>>>>> resemble > >>>>>>>>>>>> the diagram on page 300 of Claus' book. I haven't seen any > >>>>>> example > >>>>>>>>> where > >>>>>>>>>>>> camel is enlisted in an already existing transaction. I was > >>>>>> hoping > >>>>>>>>> that > >>>>>>>>>>> was > >>>>>>>>>>>> just because examples are traditionally simple but maybe it > >>>>>> wasn't > >>>>>>>>>>> designed > >>>>>>>>>>>> to do that? > >>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> Camel does not have its own TX manager etc. All we do is to > hook > >>>>>>> into > >>>>>>>>>>> the Spring TX manager. > >>>>>>>>>>> So if there is already a TX in progress, then Camel should just > >>>>>> play > >>>>>>>>>>> along, and run in that same TX. > >>>>>>>>>>> > >>>>>>>>>>> The Camel processing occurs in a Spring TX template in its - > >>>>>>>>>>> doInTransaction method. That happens when you use the > >>>>> <transacted> > >>>>>>> in > >>>>>>>>>>> the Route. > >>>>>>>>>>> > >>>>>>>>>>>> Chris > >>>>>>>>>>>> > >>>>>>>>>>>> On Thu, Apr 5, 2012 at 1:11 AM, Christian Müller < > >>>>>>>>>>>> christian.muel...@gmail.com> wrote: > >>>>>>>>>>>> > >>>>>>>>>>>>> Chris, > >>>>>>>>>>>>> may be the source code of Claus book "Camel in Action" is > >>>>>> helpful > >>>>>>>> for > >>>>>>>>>>> you > >>>>>>>>>>>>> [1]. > >>>>>>>>>>>>> > >>>>>>>>>>>>> Could you als share your datasource configuration with us? It > >>>>>> was > >>>>>>>>> not in > >>>>>>>>>>>>> your post... > >>>>>>>>>>>>> > >>>>>>>>>>>>> [1] > >>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>> > http://code.google.com/p/camelinaction/source/browse/trunk/chapter9/xa/src/test/resources/spring-context.xml > >>>>>>>>>>>>> > >>>>>>>>>>>>> Best, > >>>>>>>>>>>>> Christian > >>>>>>>>>>>>> > >>>>>>>>>>>>> On Thu, Apr 5, 2012 at 7:13 AM, Chris Geer < > >>>>>>> ch...@cxtsoftware.com> > >>>>>>>>>>> wrote: > >>>>>>>>>>>>> > >>>>>>>>>>>>>> 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 > >>>>>>>>>>>>>> > >>>>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> > >>>>>>>>>>> -- > >>>>>>>>>>> Claus Ibsen > >>>>>>>>>>> ----------------- > >>>>>>>>>>> CamelOne 2012 Conference, May 15-16, 2012: http://camelone.com > >>>>>>>>>>> FuseSource > >>>>>>>>>>> Email: cib...@fusesource.com > >>>>>>>>>>> Web: http://fusesource.com > >>>>>>>>>>> Twitter: davsclaus, fusenews > >>>>>>>>>>> Blog: http://davsclaus.blogspot.com/ > >>>>>>>>>>> Author of Camel in Action: http://www.manning.com/ibsen/ > >>>>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> > >>>>>>>>> -- > >>>>>>>>> Claus Ibsen > >>>>>>>>> ----------------- > >>>>>>>>> CamelOne 2012 Conference, May 15-16, 2012: http://camelone.com > >>>>>>>>> FuseSource > >>>>>>>>> Email: cib...@fusesource.com > >>>>>>>>> Web: http://fusesource.com > >>>>>>>>> Twitter: davsclaus, fusenews > >>>>>>>>> Blog: http://davsclaus.blogspot.com/ > >>>>>>>>> Author of Camel in Action: http://www.manning.com/ibsen/ > >>>>>>>>> > >>>>>>>> > >>>>>>> > >>>>>> > >>>>> > >>> >