camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "DEPREZ Arnaud AWL-IT" <arnaud.dep...@atos.net>
Subject RE: OSGI Transaction Propagation to Camel Route
Date Thu, 19 Apr 2012 12:24:09 GMT
Hi Chris,

Concerning your question, I don't really understand the meaning.
Can you give me more details ?

By the way, does anybody have an idea about when the 5.6 official release comes out ?
Actually, I get exactly the same problem with the XA transactionManager from Aries and ActiveMQ and I don't want to use the snapshot version.

Here is my log for more details :

14:23:04,801 | WARN  | tenerContainer-1 | PooledSession                    | 47 - org.apache.activemq.activemq-pool - 5.4.2.fuse-04-05 | 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)[43:org.apache.activemq.activemq-core:5.4.2.fuse-04-05]
        at org.apache.activemq.pool.PooledSession.close(PooledSession.java:111)[47:org.apache.activemq.activemq-pool:5.4.2.fuse-04-05]
        at org.springframework.jms.support.JmsUtils.closeSession(JmsUtils.java:108)[77:org.springframework.jms:3.0.5.RELEASE]
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:366)[77:org.springframework.jms:3.0.5.RELEASE]
        at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:263)[77:org.springframework.jms:3.0.5.RELEASE]
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1058)[77:org.springframework.jms:3.0.5.RELEASE]
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.executeOngoingLoop(DefaultMessageListenerContainer.java:1050)[77:org.springframework.jms:3.0.5.RELEASE]
        at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:947)[77:org.springframework.jms:3.0.5.RELEASE]
        at java.lang.Thread.run(Thread.java:619)[:1.6.0_14]


Arnaud Deprez

 please don't print unless you really need to

-----Original Message-----
From: Chris Geer [mailto:chris@cxtsoftware.com]
Sent: mercredi 18 avril 2012 18:43
To: users@camel.apache.org
Subject: Re: OSGI Transaction Propagation to Camel Route

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 <chris@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&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 <raul@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 <raul@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 <chris@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 <raul@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 <chris@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 <raul@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.
>> >>>>> raul@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 <chris@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 <
>> raul@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.
>> >>>>>>> raul@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 <chris@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.ibsen@gmail.com>
>> >>>>>>> wrote:
>> >>>>>>>>
>> >>>>>>>>> On Thu, Apr 5, 2012 at 5:57 PM, Chris Geer <
>> chris@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.ibsen@gmail.com
>> >>>>>>>
>> >>>>>>>>> wrote:
>> >>>>>>>>>>
>> >>>>>>>>>>> On Thu, Apr 5, 2012 at 4:59 PM, Chris Geer <
>> >>>>> chris@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.mueller@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 <
>> >>>>>>> chris@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: cibsen@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: cibsen@fusesource.com
>> >>>>>>>>> Web: http://fusesource.com
>> >>>>>>>>> Twitter: davsclaus, fusenews
>> >>>>>>>>> Blog: http://davsclaus.blogspot.com/
>> >>>>>>>>> Author of Camel in Action: http://www.manning.com/ibsen/
>> >>>>>>>>>
>> >>>>>>>>
>> >>>>>>>
>> >>>>>>
>> >>>>>
>> >>>
>>
>
>


Atos Worldline SA/NV - Chaussee de Haecht 1442 Haachtsesteenweg
- 1130 Brussels - Belgium
RPM-RPR Bruxelles-Brussel - TVA-BTW BE 0418.547.872
Bankrekening-Compte Bancaire-Bank Account 310-0269424-44
BIC BBRUBEBB - IBAN BE55 3100 2694 2444

"The information contained in this e-mail and any attachment thereto is confidential and may contain information which is protected by intellectual property rights.
This information is intended for the exclusive use of the recipient(s) named above.
This e-mail does not constitute any binding relationship or offer toward any of the addressees.
If you are not one of the addressees , one of their employees or a proxy holder entitled to hand over this message to the addressee(s), any use of the information contained herein (e.g. reproduction, divulgation, communication or distribution,...) is prohibited.
If you have received this message in error, please notify the sender and destroy it immediately after.
The integrity and security of this message cannot be guaranteed and it may be subject to data corruption, interception and unauthorized amendment, for which we accept no liability."
Mime
View raw message