...
You first define needed object in the spring configuration.
Code Block | ||||
---|---|---|---|---|
| ||||
<bean id="jmsTransactionManager" class="org.springframework.jms.connection.JmsTransactionManager">
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616"/>
</bean>
|
Then you look them up and use them to create the JmsComponent.
Code Block | ||
---|---|---|
| ||
PlatformTransactionManager transactionManager = (PlatformTransactionManager) spring.getBean("jmsTransactionManager");
ConnectionFactory connectionFactory = (ConnectionFactory) spring.getBean("jmsConnectionFactory");
JmsComponent component = JmsComponent.jmsComponentTransacted(connectionFactory, transactionManager);
component.getConfiguration().setConcurrentConsumers(1);
ctx.addComponent("activemq", component);
|
...
Outbound endpoints will automatically enlist in the current transaction context. But what if you do not want your outbound endpoint to enlist in the same transaction as your inbound endpoint? The solution is to add a Transaction Policy to the processing route. You first have to define transaction policies that you will be using. The policies use a spring TransactionTemplate under the covers for declaring the transaction demarcation to use. So you will need to add something like the following to your spring xml:
Code Block | ||||
---|---|---|---|---|
| ||||
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="jmsTransactionManager"/>
</bean>
<bean id="PROPAGATION_REQUIRES_NEW" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="jmsTransactionManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
</bean>
|
Then in your SpringRouteBuilder, you just need to create new SpringTransactionPolicy objects for each of the templates.
Code Block | ||||
---|---|---|---|---|
| ||||
public void configure() {
...
Policy requried = bean(SpringTransactionPolicy.class, "PROPAGATION_REQUIRED"));
Policy requirenew = bean(SpringTransactionPolicy.class, "PROPAGATION_REQUIRES_NEW"));
...
}
|
Once created, you can use the Policy objects in your processing routes:
Code Block | ||||
---|---|---|---|---|
| ||||
// Send to bar in a new transaction
from("activemq:queue:foo").policy(requirenew).to("activemq:queue:bar");
// Send to bar without a transaction.
from("activemq:queue:foo").policy(notsupported ).to("activemq:queue:bar");
|
...
If you are using OSGi Blueprint then you most likely have to explicit declare a policy and refer to the policy from the transacted in the route.
Code Block | ||||
---|---|---|---|---|
| ||||
<bean id="required" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="jmsTransactionManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED"/>
</bean>
|
And then refer to "required" from the route:
Code Block | ||||
---|---|---|---|---|
| ||||
<route>
<from uri="activemq:queue:foo"/>
<transacted ref="required"/>
<to uri="activemq:queue:bar"/>
</route>
|
...
First of all we setup the usual spring stuff in its configuration file. Here we have defined a DataSource to the HSQLDB and a most importantly
the importantly the Spring DataSoruce DataSource TransactionManager that is doing the heavy lifting of ensuring our transactional policies. You are of course free to use any
of any of the Spring based TransactionMananger, eg. if you are in a full blown J2EE container you could use JTA or the WebLogic or WebSphere specific managers.
As we use the new convention over configuration we do not need to configure a transaction policy bean, so we do not have any PROPAGATION_REQUIRED
beans.
All All the beans needed to be configured is standard Spring beans only, eg. there are no Camel specific configuration at all.
...
Notice how we have configured the onException
in the 2nd route to indicate in case of any exceptions we should handle it and just rollback this transaction.
This is done using the markRollbackOnlyLast
which tells Camel to only do it for the current transaction and not globally.
...
Include Page | ||||
---|---|---|---|---|
|