In this sample we want to ensure that two endpoints are under transaction control. These two endpoints insert data into a database. The sample appears in full in a unit test.
First of all we setup the normal Spring configuration file. Here we have defined a DataSource to the HSQLDB and a most importantly the Spring DataSource TransactionManager that is doing the heavy lifting of ensuring our transactional policies. You are of course free to use 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 the beans needed to be
configured is standard Spring beans only, eg. there are
no Camel specific configuration at all.
<!-- this example uses JDBC so we define a data source --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="org.hsqldb.jdbcDriver"/> <property name="url" value="jdbc:hsqldb:mem:camel"/> <property name="username" value="sa"/> <property name="password" value=""/> </bean> <!-- Spring transaction manager --> <!-- that Camel will use for transacted routes --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <!-- bean for book business logic --> <bean id="bookService" class="org.apache.camel.spring.interceptor.BookService"> <property name="dataSource" ref="dataSource"/> </bean>
Then we are ready to define our Camel routes. We have two routes: 1 for success conditions, and 1 for a forced rollback condition. This is after all based on a unit test. Notice that we mark each route as transacted using the transacted tag.
<camelContext xmlns="http://camel.apache.org/schema/spring"> <route> <from uri="direct:okay"/> <!-- We mark this route as transacted. Camel will lookup the Spring transaction manager and use it by default. We can optimally pass in arguments to specify a policy to use that is configured with a Spring transaction manager of choice. However Camel supports convention over configuration as we can just use the defaults out of the box suitable for most situations --> <transacted/> <setBody> <constant>Tiger in Action</constant> </setBody> <bean ref="bookService"/> <setBody> <constant>Elephant in Action</constant> </setBody> <bean ref="bookService"/> </route> <route> <from uri="direct:fail"/> <!-- we mark this route as transacted. See comments above. --> <transacted/> <setBody> <constant>Tiger in Action</constant> </setBody> <bean ref="bookService"/> <setBody> <constant>Donkey in Action</constant> </setBody> <bean ref="bookService"/> </route> </camelContext>
That is all that is needed to configure a Camel route as being transacted. Just remember to use the transacted DSL. The rest is standard Spring XML to setup the transaction manager.