user3615185
user3615185

Reputation: 55

How to configure Single transaction manager for multiple Datasources(three oracle dbs)?

My Project is in Spring Batch. I am using three transaction manager for three different datasources.Here, I am facing a problem that if failure occurs in one of the db persistence , Rollback will be done only on that datasource, not on the other two datasources. I want to synchronize all the datasources, so that rollback will be done all three. Is it Possible to have single transaction manger for all three datasources? Is so, how to configure it? Please anyone help me with this. Find below my configuration details,

<bean id="firstDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close" primary="true">
        <property name="driverClassName" value="${jdbc.first.driver}" />
        <property name="url" value="${jdbc.first.url}" />
        <property name="username" value="${jdbc.first.username}" />
        <property name="password" value="${jdbc.first.password}" />
        <property name="removeAbandoned" value="true" />
        <property name="initialSize" value="${jdbc.initial.pool.size}" />
        <property name="maxActive" value="${jdbc.max.active}" />
    </bean>

    <bean id="secondDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${jdbc.second.driver}" />
        <property name="url" value="${jdbc.second.url}" />
        <property name="username" value="${jdbc.second.username}" />
        <property name="password" value="${jdbc.second.password}" />
        <property name="removeAbandoned" value="true" />
        <property name="initialSize" value="${jdbc.initial.pool.size}" />
        <property name="maxActive" value="${jdbc.max.active}" />
    </bean>

    <bean id="thirdDataSource" class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="${jdbc.third.driver}" />
        <property name="url" value="${jdbc.third.url}" />
        <property name="username" value="${jdbc.third.username}" />
        <property name="password" value="${jdbc.third.password}" />
        <property name="removeAbandoned" value="true" />
        <property name="initialSize" value="${jdbc.initial.pool.size}" />
        <property name="maxActive" value="${jdbc.max.active}" />
    </bean>


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

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

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

Upvotes: 0

Views: 1064

Answers (1)

Ricardo Vila
Ricardo Vila

Reputation: 1632

Yes, it is possible but you must change several things. You need a global transaction manager that is capable of 2-phase-commit. You can use a JTA implementation that suport this like Atomikos, Spring's JtaTransactionManager or JBoss JTA support. I've used the last one with Spring and JPA (Hibernate implementation), and in this case it's very easey to configure. You only need to tell Hibernate that the transaction manager will be the JBoss JTA implementation:

<prop key="hibernate.transaction.jta.platform">
  org.hibernate.service.jta.platform.internal.JBossAppServerJtaPlatform
</prop>

Have in mind that for 2-phase-commit you wuold need to change your Datasources to XA Datasources.

Upvotes: 1

Related Questions