After an upgrade to 5.6-SNAPSHOT everything works as expected. I'm still curious about my last question though :)
Thank you all for your help. Chris On Tue, Apr 17, 2012 at 6:28 PM, Chris Geer <ch...@cxtsoftware.com> wrote: > 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/ >> >>>>>>>>> >> >>>>>>>> >> >>>>>>> >> >>>>>> >> >>>>> >> >>> >> > >