camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Raul Kripalani <r...@fusesource.com>
Subject Re: OSGI Transaction Propagation to Camel Route
Date Tue, 17 Apr 2012 20:48:01 GMT
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/
>>>>>>
>>>>>
>>>>
>>>
>>

Mime
View raw message