JPA 多事务管理器 [英] JPA Multiple Transaction Managers

查看:27
本文介绍了JPA 多事务管理器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我想使用基于注解的事务 (@Transactional),不要乱用 TransactionStatus 提交、保存和回滚.

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

I have one applicationContext.xml file, and it has two org.springframework.orm.jpa.JpaTransactionManager (each with its own persistence unit, different databases) configured in a Spring middleware custom application.

I want to use annotation based transactions (@Transactional), to not mess around with TransactionStatus commit, save, and rollback.

A coworker mentioned that something gets confused doing this when there are multiple transaction managers, even though the context file is set configured correctly (the references go to the correct persistence unit. Anyone ever see an issue?

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

这就是我对 JPA 的看法,这是两个不同的 Spring bean,它们是事务管理器.

In your config, would you have two transaction managers? Would you have txManager1 and txManager2?

That's what I have with JPA, two different Spring beans that are transaction managers.

推荐答案

我猜你有 2 个选择

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

If your use-cases never require updates to both databases within the same transaction, then you can use two JpaTransactionManagers, but I'm not sure you will be able to use the @Transactional approach? In this case, you would need to fallback on the older mechanism of using a simple TransactionProxyFactoryBean to define transaction boundaries, eg:

<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 状态:

If you are require a transaction spanning both databases, then you will need to use a JTA transaction manager. The API states:

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

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 事务管理器.在我们的应用程序中,我们使用类似于以下的配置:

What this means is that you will need to provide a JTA transaction manager. In our application, we use config similar to the following:

<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 事务管理器(但我自己还没有尝试过)

If you are deploying within an appserver, then the spring JtaTransactionManager needs to do a lookup to the real XA-compliant JTA transaction manager provided by the appserver. However, you can also use a standalone JTA transaction manager (but I haven't tried this myself yet)

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

As for configuring the Jpa persistence provider, I'm not that familiar. What JPA persistence provider are you using?

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

The code above is based on our approach, where we were using native Hibernate as opposed to Hibernate's JPA implementation. In this case, we were able to get rid of the two HibernateTransactionManager beans, and simply ensure that both SessionFactories were injected with the same JTA TM, and then use the tx:annotation-driven element.

希望能帮到你

这篇关于JPA 多事务管理器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆