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

我想使用基于注释的事务(@Transactional),以免混淆 TransactionStatus 提交、保存和回滚。

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


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

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

有帮助吗?

解决方案

我想你有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 事务管理器。这 应用程序编程接口 状态:

该事务管理器适用于使用单个 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,并简单地确保两个 SessionFactory 都注入相同的 JTA TM,然后使用 tx:annotation-driven 元素。

希望这可以帮助

其他提示

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

在内部,Spring 的事务管理器都使用 Spring 的 TransactionSynchronizationManager,它在静态 ThreadLocal 变量中保存一堆关键状态,因此保证事务管理器能够破坏彼此的状态。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top