How to use BTM as the transaction manager with Spring 2.5.x
This document has not been updated for version 1.3.x yet but you can still read the 1.2 version as most of its content is relevant for both versions.
These instructions have been verified against BTM 1.3.2.
|Table of Contents|
Step 1: Copy the BTM jars
Include the following jars from the BTM distribution into your classpath:
- geronimo-jms_1.1_spec-1.0.1.jar (only if you are going to use JMS)
- slf4j-jdk14-1.5.2.jar (or any other one available here)
Step 2: Configure connection pools beans
The first things you will need to configure are the connection pools.
Here is a sample bean configuration using Embedded Derby:
<bean id="derbyDataSource" class="bitronix.tm.resource.jdbc.PoolingDataSource" init-method="init" destroy-method="close"> <property name="className" value="org.apache.derby.jdbc.EmbeddedXADataSource" /> <property name="uniqueName" value="derbydb" /> <property name="maxPoolSize" value="5" /> <property name="driverProperties"> <props> <prop key="databaseName">derbydb</prop> </props> </property> </bean>
Since the pools are created via the BTM API (ie: not with ResourceLoader) it is up to the API user to manage the lifecycle of the pools, mainly calling
Step 3: Configure BTM beans
The second thing you need to do is configure beans for BTM.
<!-- Bitronix Transaction Manager embedded configuration --> <bean id="btmConfig" factory-method="getConfiguration" class="bitronix.tm.TransactionManagerServices"> <property name="serverId" value="spring-btm" /> </bean> <!-- create BTM transaction manager --> <bean id="BitronixTransactionManager" factory-method="getTransactionManager" class="bitronix.tm.TransactionManagerServices" depends-on="btmConfig" destroy-method="shutdown" />
Step 4: Configure Spring PlatformTransactionManager
Next, you need to create a Spring PlatformTransactionManager. There are many of them but the one we are interested in is the JtaTransactionManager. This is required as Spring internally uses
PlatformTransactionManager for all transactional work.
<!-- Spring JtaTransactionManager --> <bean id="JtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionManager" ref="BitronixTransactionManager" /> <property name="userTransaction" ref="BitronixTransactionManager" /> </bean>
This is really all you need to get JTA support with BTM inside Spring. You could directly make use of the
JtaTransactionManager bean in your code but there are more elegant solutions: using Sping's AOP support to get declarative transaction management.
Step 5: Configure declarative transaction management
This can easily be achieved thanks to Spring's TransactionProxyFactoryBean.
The idea behind it is to wrap your bean with a Spring-generated proxy that will intercept calls and perform transaction management according to a configuration.
Here is short example:
<bean id="MyObjectFacade" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="JtaTransactionManager" /> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED, -Exception</prop> </props> </property> <property name="target" ref="MyObject" /> </bean>
This expects a
MyObject bean to also be configured. You should then make use of the
MyObjectFacade bean that will start a new transaction on any method call if no transaction is already running (the
<prop key="*">PROPAGATION_REQUIRED piece), commit the transaction when the method returns or rollback the transaction if any exception is thrown (the
, -Exception</prop> piece).
If you need more details on what can be done and how things are working refer to the TransactionProxyFactoryBean class javadoc.