JPA多个事务管理器
问题内容:
我有一个applicationContext.xml文件,它在Spring中间件自定义应用程序中配置了两个org.springframework.orm.jpa.JpaTransactionManager(每个都有自己的持久性单元,不同的数据库)。
我想使用基于注释的事务(@Transactional),以免使TransactionStatus提交,保存和回滚。
一位同事提到,即使有多个事务管理器,即使上下文文件的配置正确(引用指向正确的持久性单元。有人看到问题了吗?),这样做有些混乱。
在您的配置中,您将有两个事务管理器吗?您有txManager1和txManager2吗?
这就是JPA的功能,这是两个不同的Spring Bean,它们是事务管理器。
问题答案:
我猜你有两个选择
如果您的用例从不要求在同一事务中同时更新两个数据库,则可以使用两个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元素。
希望这可以帮助