我正在寻找一种通过Spring / JTA将两个数据源的CRUD放入一个事务中的方法,但是有以下问题:


datasource而不是JNDI制成org.apache.commons.dbcp.BasicDataSource可以吗?
有两个参数可以初始化JtaTransactionManager:

public JtaTransactionManager(UserTransaction userTransaction,
                     TransactionManager transactionManager)


Spring document

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


如果我有一个数据源DS_A和另一个数据源DS_B,它们都需要在同一个事务管理器中,那么应该是UserTransaction以及如何定义TransactionManager,就像我刚刚创建JtaTransactionManager一样,这意味着另一个JtaTransactionManager?而且看起来两个参数都不是必需的,因此JtaTransactionManager如何从以下位置检测到它们:

<context:annotation-driven/>
<tx:jta-transaction-manager/>

如果一切都在应用程序上下文中定义良好,那么如果有两个数据源,应该在@Transactional批注中引用哪个事务管理器bean?

最佳答案

可以确定数据源是由org.apache.commons.dbcp.BasicDataSource而不是JNDI构成的吗?



JNDI只是访问数据源的一种方式。要在数据库之间分配事务,您需要使用事务数据源。例如microsoft sql server jdbc驱动程序具有事务性数据源-com.microsoft.sqlserver.jdbc.SQLServerXADataSource



如果我有一个数据源DS_A和另一个数据源DS_B,它们都需要在同一个事务管理器中,则应该是
就我而言,UserTransaction以及如何定义TransactionManager
创建JtaTransactionManager,是否意味着另一个
JtaTransactionManager?



JtaTransactionManager是JTA的实现,委托给后端JTA提供程序。因此,您将需要一个实现分布式事务的JTA提供程序。 Bitronix是这样的JTA提供程序之一。需要各种配置

一个。 hibernate.properties

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


b。定义事务管理器和用户事务bean

    <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。事务拦截器和注释支持

    <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还引入了@EnableTransactionManagement注释,因此另一种配置方式是

@Configuration
@EnableTransactionManagement
public class PersistenceJPAConfig{

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

   @Bean
   public PlatformTransactionManager transactionManager(){
      //configure JTA transaction manager
      return transactionManager;
   }
}




如果一切都在应用程序上下文中定义良好,那么应该在@Transactional批注中引用哪个事务管理器Bean,
是否有两个数据源?



我认为上面的解释应该回答这个问题。只有一个事务管理器来管理两个数据源上的事务。这些称为分布式事务,它们使用两阶段提交协议。通过this链接获取有关XA事务的介绍性文章。

10-06 02:50