Dreamer
Dreamer

Reputation: 7551

Questions regarding JtaTransactionManager

I am looking for a way to put CRUD of two data source into one transaction by Spring/JTA, but have following questions:

  1. Is it ok that the datasource is is made oforg.apache.commons.dbcp.BasicDataSource instead of JNDI?
  2. There are two parameters to intitiate a JtaTransactionManager:

    public JtaTransactionManager(UserTransaction userTransaction,
                         TransactionManager transactionManager)
    

    From Spring document:

    userTransaction - the JTA UserTransaction to use as direct reference
    transactionManager - the JTA TransactionManager to use as direct reference
    

    If I have a datasource DS_A and another datasource DS_B, which both requires within the same transaction manager, then which should be the UserTransaction and how to define the TransactionManager, as I am just creating the JtaTransactionManager, does it mean another JtaTransactionManager? Also it looks both parameters are not required so how JtaTransactionManager can detect them from:

    <context:annotation-driven/>
    <tx:jta-transaction-manager/> 
    
  3. If everything is well defined in application context, then which transaction manager bean should referred in @Transactional annotation, if there are two datasources?

Upvotes: 0

Views: 985

Answers (1)

Andy Dufresne
Andy Dufresne

Reputation: 6180

  1. Is it ok that the datasource is is made oforg.apache.commons.dbcp.BasicDataSource instead of JNDI?

JNDI is just a way to access the datasource. To have distributed transactions across databases you need to use transactional data sources. For e.g. microsoft sql server jdbc driver has a transactional data source - com.microsoft.sqlserver.jdbc.SQLServerXADataSource.

  1. If I have a datasource DS_A and another datasource DS_B, which both requires within the same transaction manager, then which should be the UserTransaction and how to define the TransactionManager, as I am just creating the JtaTransactionManager, does it mean another JtaTransactionManager?

JtaTransactionManager is an implementation for JTA, delegating to a backend JTA provider. So you would need a JTA provider that implements distributed transactions. Bitronix is one such JTA provider. There are various configurations needed

a. hibernate.properties

<prop key="hibernate.transaction.factory_class">
<prop key="hibernate.transaction.manager_lookup_class">
<property name="useTransactionAwareDataSource" value="true"/>

b. Defining transaction manager and usertransaction beans

    <bean id="BitronixTransactionManager" factory-method="getTransactionManager"
          class="bitronix.tm.TransactionManagerServices" depends-on="bitronixConfiguration"
          destroy-method="shutdown">
    </bean>

    <bean id="transactionManager"                           class="org.springframework.transaction.jta.JtaTransactionManager">
        <property name="transactionManager" ref="BitronixTransactionManager"/>
        <property name="userTransaction" ref="BitronixTransactionManager"/>
        <property name="allowCustomIsolationLevels" value="true"/>
    </bean>

c. Transaction Interceptor and annotation support

    <bean id="annotationTransactionSource"
        class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>


    <bean id="transactionInterceptor" 
          class="org.springframework.transaction.interceptor.TransactionInterceptor">
        <property name="transactionManager">
            <ref local="transactionManager"/>
        </property>
        <property name="transactionAttributeSource">
            <ref local="annotationTransactionSource"/>
        </property>
    </bean>

Spring 3.1 also introduced a @EnableTransactionManagement annotation so another way to configure would be

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

   @Bean
   public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
      ...
   }

   @Bean
   public PlatformTransactionManager transactionManager(){
      //configure JTA transaction manager
      return transactionManager;
   }
}
  1. If everything is well defined in application context, then which transaction manager bean should referred in @Transactional annotation, if there are two datasources?

I assume the above explanation should answer this question. There is just one transaction manager managing transactions over the two data sources. These are called distributed transaction and they use a two phase commit protocol. Go through this link for an introductory article on XA transactions.

Upvotes: 1

Related Questions