12

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

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

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


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

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

4

2 回答 2

10

我猜你有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 元素。

希望这可以帮助

于 2008-09-16T23:56:40.503 回答
4

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

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

于 2008-11-11T13:30:50.833 回答