If you want to influence the way a transactional client creates new transactions, you can do so by specifying a transaction policy for it. In particular, Spring transaction policies enable you to specify a propagation behavior for your transaction. For example, if a transactional client is about to create a new transaction and it detects that a transaction is already associated with the current thread, should it go ahead and create a new transaction, suspending the old one? Or should it simply let the existing transaction take over? These kinds of behavior are regulated by specifying the propagation behavior on a transaction policy.
Transaction policies are instantiated as beans in Spring XML. You can then
reference a transaction policy by providing its bean ID as an argument to the
transacted() DSL command. For example, if you want to initiate
transactions subject to the behavior, PROPAGATION_REQUIRES_NEW, you
could use the following route:
from("file:src/data?noop=true")
.transacted("PROPAGATION_REQUIRES_NEW")
.beanRef("accountService","credit")
.beanRef("accountService","debit")
.to("file:target/messages"); Where the PROPAGATION_REQUIRES_NEW argument specifies the bean ID of
a transaction policy bean that is configured with the
PROPAGATION_REQUIRES_NEW behavior (see Example 5.1).
Fuse Mediation Router lets you define Spring transaction policies using the
org.apache.camel.spring.spi.SpringTransactionPolicy class (which is
essentially a wrapper around a native Spring class). The
SpringTransactionPolicy class encapsulates two pieces of
data:
A reference to a transaction manager (of
PlatformTransactionManagertype).A propagation behavior.
For example, you could instantiate a Spring transaction policy bean with
PROPAGATION_MANDATORY behavior, as follows:
<beans ...>
<bean id="PROPAGATION_MANDATORY "class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_MANDATORY"/>
</bean>
...
</beans>The following propagation behaviors are supported by Spring (where these values were originally modelled on the propagation behaviors supported by J2EE):
PROPAGATION_MANDATORYSupport a current transaction; throw an exception if no current transaction exists.
PROPAGATION_NESTEDExecute within a nested transaction if a current transaction exists, else behave like
PROPAGATION_REQUIRED.![[Note]](imagesdb/note.gif)
Note Nested transactions are not supported by all transaction managers.
PROPAGATION_NEVERDo not support a current transaction; throw an exception if a current transaction exists.
PROPAGATION_NOT_SUPPORTEDDo not support a current transaction; rather always execute non-transactionally.
![[Note]](imagesdb/note.gif)
Note This policy requires the current transaction to be suspended, a feature which is not supported by all transaction managers.
PROPAGATION_REQUIRED(Default) Support a current transaction; create a new one if none exists.
PROPAGATION_REQUIRES_NEWCreate a new transaction, suspending the current transaction if one exists.
![[Note]](imagesdb/note.gif)
Note Suspending transactions is not supported by all transaction managers.
PROPAGATION_SUPPORTSSupport a current transaction; execute non-transactionally if none exists.
Example 5.1 shows how to define transaction policy beans for all of the supported propagation behaviors. For convenience, each of the bean IDs matches the specified value of the propagation behavior value, but in practice you can use whatever value you like for the bean IDs.
Example 5.1. Transaction Policy Beans
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
...
<bean id="PROPAGATION_MANDATORY "class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_MANDATORY"/>
</bean>
<bean id="PROPAGATION_NESTED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_NESTED"/>
</bean>
<bean id="PROPAGATION_NEVER" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_NEVER"/>
</bean>
<bean id="PROPAGATION_NOT_SUPPORTED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_NOT_SUPPORTED"/>
</bean>
<!-- This is the default behavior. -->
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
</bean>
<bean id="PROPAGATION_REQUIRES_NEW" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRES_NEW"/>
</bean>
<bean id="PROPAGATION_SUPPORTS" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager"/>
<property name="propagationBehaviorName" value="PROPAGATION_SUPPORTS"/>
</bean>
</beans>![]() | Tip |
|---|---|
If you want to paste any of these bean definitions into your own Spring XML
configuration, remember to customize the references to the transaction manager.
That is, replace references to |
A simple way of demonstrating that transaction policies have some effect on a
transaction is to insert a PROPAGATION_NEVER policy into the middle of
an existing transaction, as shown in the following route:
from("file:src/data?noop=true")
.transacted()
.beanRef("accountService","credit")
.transacted("PROPAGATION_NEVER")
.beanRef("accountService","debit");Used in this way, the PROPAGATION_NEVER policy inevitably aborts
every transaction, leading to a transaction rollback. You should easily be able to
see the effect of this on your application.
![]() | Note |
|---|---|
Remember that the string value passed to |
The preceding route can be also be defined in Spring XML, as follows:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ... >
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:src/data?noop=true"/>
<transacted/>
<bean ref="accountService" method="credit"/>
<transacted ref="PROPAGATION_NEVER"/>
<bean ref="accountService" method="debit"/>
</route>
</camelContext>
</beans>





![[Tip]](imagesdb/tip.gif)


