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&amp;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/
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>
> >>>
>

Reply via email to