camel-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tourist604 <i...@skrypnyk.net>
Subject Transactions in camel: more questions (1.4.0)
Date Sun, 10 Aug 2008 23:00:34 GMT

Hi,

I have been trying to figure out how to use transactions in camel.

My original requirements are simple:
While in transaction, do:
1. Consume a JMS message
2. Process it and route it to an http endpoint
3. If http resets connection or returns with invalid status,
4. Retry the message using DeadLetterChannel facilities and exception based
handling and re-route, if all fails, elsewhere.

While trying to figure out how to use transaction consumption of JMS
messages in camel, I have found this post in the forum: 
http://www.nabble.com/JMS-Transactions---How-To-td15168958s22882.html#a15168958

This post led me to believe that I need to add this to my route IN ADDITION
to specifying the JMSComponent as transactional in the spring context:

--- spring context snippet: ---

	<bean id="activemq"
		class="org.apache.camel.component.jms.JmsComponent">
		<property name="connectionFactory">
			<ref bean="jmsConnectionFactory" />
		</property>
		<property name="transactionManager">
			<ref bean="jmsTransactionManager" />
		</property>
		<property name="transacted">
			<value>true</value>
		</property>
	</bean>


--- end of spring contxt snippet: ---

--- route definition snippet: ---
 Policy required = new SpringTransactionPolicy(bean(
                        TransactionTemplate.class, "PROPAGATION_REQUIRED")); 
 from( "activemq:myqueue" ).policy( required )...

--- end of route definition snippet ----

The configuration above fails in one major way: it doesn't allow me to use
the DeadLetterChannel to handle errors.

After spending a few days battling with this configuration, I have come to
the following conclusions:

1. Attaching a "PROPAGATION_REQUIRED" policy to the route does not initiate
the transaction. The transaction is initiated by JmsComponent; in fact, it's
initiated by Spring itself via the Message-Driven POJO support.
2. Attaching this policy will cause a flag to be set on the exchange which
will make DeadLetterChannel skip altogether, thereby foregoing its (in my
opinion great!!!) mechanism of discriminately handling different exceptions
in different ways and re-routing the message elsewhere. The errorHandler
cannot be placed after the transactional policy in the route; it will always
be placed before by the route "start" code.
3. On error, org.apache.camel.spring.spi.TransactionInterceptor which is
injected by adding the PROPAGATION_REQUIRED policy returns with 3 conditions
which may be interpreted as rolling back the transaction:

line: 128 if (rce != null) {
                    redeliveryData.previousRollback = true;
                    if (activeTx) {
                        status.setRollbackOnly();
                        LOG.debug("Transaction rollback");
                    }
                    throw rce;
}

a) status.setRollbackOnly(): I tried skipping this flag, and transaction
still rolled back so it appears to be ineffectual
b) "throw rce" will cause the TransactionTemplate to perform a rollback
c) the original exchange may contain an exception which will cause the
message listener to re-throw it.

(the above 3 things may be confusing to anyone trying to debug the
transactional handling)

4. NOT ADDING the policy to the route still makes the route operate within
the transaction initated by the JmsComponent and spring **AND**
DeadLetterChannel is happily available to handle your retries and re-routing
WITHIN the original transaction.
5. If I **send** (while re-routing) a message within the same route using
the same JmsComponent, configured with the same transaction manager, the
default "PROPAGATION_REQUIRED" propagation behaviour in spring's
TransactionTemplate will cause this operation to be enlisted within the
original transaction initiated by the JMS consumer thus rendering the whole
route to operate within the same transaction (here we are using the same
transactional data sources, i.e. the same activemq broker, so no distributed
semantics).

Can anyone confirm the validity of these assumptions? 

I would greatly appreciate it as the transactional behaviour in camel is a
critical aspect of a our camel-based integration solution.

Thanks,
--Bill
-- 
View this message in context: http://www.nabble.com/Transactions-in-camel%3A-more-questions-%281.4.0%29-tp18917974s22882p18917974.html
Sent from the Camel - Users mailing list archive at Nabble.com.


Mime
View raw message