Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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>
like image 935
gioni_go Avatar asked Jan 17 '12 10:01

gioni_go


People also ask

Is it possible to define multiple transaction manager in Spring?

You just need to create two transaction managers and inject them with the appropriate connection. But I must ask the question: why do you think you need two transaction managers? You can have more than one database connection.

What happens if one @transactional annotated method is calling another @transactional annotated method on the same object instance?

If you call a method with a @Transactional annotation from a method with @Transactional within the same instance, then the called methods transactional behavior will not have any impact on the transaction.

Does Spring support nested transactions?

Nested transactions in Spring are just JDBC / database savepoints. If you don't know what a savepoint is, have a look at this tutorial, for example. Note that savepoint support is dependent on your JDBC driver/database.

How nested transactions work in Spring?

If one of those sub-units encounters a problem (runtime exception by default) then the nested transaction will roll back internally through something called savepoints but the top level transaction will be allowed to continue.


1 Answers

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

like image 83
tolitius Avatar answered Nov 30 '22 04:11

tolitius