【问题标题】:JPA Multiple Transaction ManagersJPA 多事务管理器
【发布时间】:2010-09-09 16:41:18
【问题描述】:

我有一个 applicationContext.xml 文件,它在 Spring 中间件自定义应用程序中配置了两个 org.springframework.orm.jpa.JpaTransactionManager(每个都有自己的持久性单元,不同的数据库)。

我想使用基于注释的事务 (@Transactional),而不是搞乱 TransactionStatus 提交、保存和回滚。

一位同事提到,当有多个事务管理器时,即使上下文文件设置正确(引用转到正确的持久性单元),也会感到困惑。 有人见过问题吗?


在您的配置中,您会有两个事务管理器吗? 你会有 txManager1 和 txManager2 吗?

这就是我在 JPA 中所拥有的,两个不同的 Spring bean 是事务管理器。

【问题讨论】:

    标签: java spring orm jpa transactions


    【解决方案1】:

    您可以拥有两个 Spring 事务管理器的唯一情况是您永远不会同时打开两个事务。这本质上与分布式事务无关 - 即使您希望两个数据源具有完全独立(但可能在时间上重叠)的事务生命周期,同样的限制也适用。

    在内部,Spring 的事务管理器都使用 Spring 的 TransactionSynchronizationManager,它在静态 ThreadLocal 变量中保留了一堆关键状态,因此事务管理器可以保证相互之间的状态。

    【讨论】:

      【解决方案2】:

      我猜你有两个选择

      如果您的用例从不需要在同一事务中更新两个数据库,那么您可以使用两个 JpaTransactionManager,但我不确定您是否能够使用 @Transactional 方法?在这种情况下,您需要回退到使用简单TransactionProxyFactoryBean 来定义事务边界的旧机制,例如:

      <bean id="firstRealService" class="com.acme.FirstServiceImpl"/>
      <bean id="firstService"  
          class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          <property name="transactionManager" ref="firstJpaTm"/>
          <property name="target" ref="firstRealService"/>
          <property name="transactionAttributes">
              <props>
                 <prop key="insert*">PROPAGATION_REQUIRED</prop>
                 <prop key="update*">PROPAGATION_REQUIRED</prop>
                 <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
              </props>
          </property>
      </bean>
      <!-- similar for your second service -->
      

      如果您需要跨两个数据库的事务,那么您将需要使用 JTA 事务管理器。 API 声明:

      此事务管理器适用于使用单个 JPA EntityManagerFactory 进行事务数据访问的应用程序。 JTA(通常通过 JtaTransactionManager)对于访问同一事务中的多个事务资源是必需的。请注意,您需要相应地配置您的 JPA 提供程序以使其参与 JTA 事务。

      这意味着您需要提供一个 JTA 事务管理器。在我们的应用程序中,我们使用类似于以下的配置:

      <tx:annotation-driven transaction-manager="txManager"/>
      
      <bean id="txManager" 
          class="org.springframework.transaction.jta.JtaTransactionManager">
          <property name="transactionManagerName" value="appserver/jndi/path" />
      </bean>
      

      如果您在应用服务器中进行部署,那么 spring JtaTransactionManager 需要对应用服务器提供的真正符合 XA 的 JTA 事务管理器进行查找。但是,您也可以使用独立的 JTA 事务管理器(但我自己还没有尝试过)

      关于配置 Jpa 持久化提供程序,我不是很熟悉。您使用的是什么 JPA 持久性提供程序?

      上面的代码基于我们的方法,我们使用的是本机 Hibernate,而不是 Hibernate 的 JPA 实现。在这种情况下,我们能够摆脱两个 HibernateTransactionManager bean,并简单地确保两个 SessionFactories 都注入了​​相同的 JTA TM,然后使用 tx:annotation-driven 元素。

      希望对你有帮助

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-24
      • 2011-12-24
      • 1970-01-01
      • 1970-01-01
      • 2018-12-30
      • 2019-01-24
      • 1970-01-01
      相关资源
      最近更新 更多