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