我有一个applicationContext.xml文件,它在Spring中间件自定义应用程序中配置了两个org.springframework.orm.jpa.JpaTransactionManager(每个都有自己的持久性单元,不同的数据库)。
我想使用基于注释的事务(@Transactional),以免与TransactionStatus提交,保存和回滚有关。
一位同事提到,即使有多个事务管理器,但上下文文件的配置正确(引用指向正确的持久性单元),有些事情还是让人困惑。
有人看到过问题吗?
在您的配置中,您将有两个事务管理器吗?
您有txManager1和txManager2吗?
这就是我使用JPA所拥有的东西,这两个是事务管理器的不同Spring Bean。
我猜你有两个选择
如果您的用例从不需要在同一事务中同时更新两个数据库,则可以使用两个JpaTransactionManager,但是我不确定您是否可以使用@Transactional方法?在这种情况下,您将需要回退到使用简单的TransactionProxyFactoryBean定义事务边界的旧机制,例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <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指出:
This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.
这意味着您将需要提供一个JTA事务管理器。在我们的应用程序中,我们使用类似于以下内容的配置:
1 2 3 4 5 6
| <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变量中保留了一堆关键状态,因此可以确保事务管理器在彼此的状态上脚。