gioni_go
gioni_go

Reputation: 99

Spring multiple transaction managers, single transaction

I have a complex situation where I have to use 2 different databases, there for I use 2 different transaction managers. Is there a way in Spring to link these transaction managers to work in a single transaction ? In case of an exception on the second dataSource changes on the first should be rolled-back.

<bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
abstract="true">
 <property name="transactionManager" ref="transactionManager" />
 <property name="transactionAttributes">
  <props>
    <prop key="insert*">PROPAGATION_REQUIRED</prop>
    <prop key="update*">PROPAGATION_REQUIRED</prop>
    <prop key="save*">PROPAGATION_REQUIRED</prop>
    <prop key="remove*">PROPAGATION_REQUIRED</prop>
    <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
  </props>
 </property>
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
 <property name="url" value="jdbc:oracle:thin:@dummyHost:1521:dummySID" />
 <property name="username" value="owner" />
 <property name="password" value="password" />
</bean>

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource" />
</bean>

<bean id="dataSource2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
 <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
 <property name="url" value="jdbc:oracle:thin:@dummyHost2:1521:dummySID2" />
 <property name="username" value="owner" />
 <property name="password" value="password" />
</bean>

<bean id="transactionManager2" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
 <property name="dataSource" ref="dataSource2" />
</bean>

Upvotes: 7

Views: 6238

Answers (3)

tolitius
tolitius

Reputation: 22499

You can use Spring's JtaTransactionManager to make sure both DBs are transacted with a single transaction manager.

Note, you would have to choose an underlying implementation which can either be a container's one: e.g. WebLogic, WebSphere and OC4J, etc.. or a stand alone, even an open source one: e.g. Atomikos.

HOWEVER

XA transaction management complicates things (configuration / performance / problem resolution / maintenance / etc.). And in a lot of cases, it can be avoided by clever patterns.

To get a solid understanding on whether you need to use XA ( e.g. distributed ) transaction manager, take a look at this fantastic article by Spring's own Dave Syer: Distributed transactions in Spring, with and without XA

Upvotes: 5

Aravind A
Aravind A

Reputation: 9697

For routing through multiple datasource, You could use abstractRoutingDataSource but if you have requirements like one rollbackack affecting another you would need a JtaTransactionManager for distributed txn management .

Upvotes: 0

JB Nizet
JB Nizet

Reputation: 691635

You need a global transaction manager which supports 2-phase-commit (XA). Several independent and free ones are available. I've used Bitronix in a Spring-based project, but there is also Atomikos, and probably others. See http://en.wikipedia.org/wiki/Java_Transaction_API#Opensource_JTA_implementations

Upvotes: 4

Related Questions