如何配置事务管理以在 Spring 中使用 2 个不同的数据库?

发布于 2024-08-16 05:50:49 字数 314 浏览 7 评论 0原文

我有 2 个数据库(MySql 和 HSQLDB)。我配置了 2 个数据源和 2 个 EntityManagerFactory bean。我还可以配置 2 个相应的 JpaTransactionManager beans。

但我不知道如何指定应使用其中哪些来管理具体服务类的事务。我想使用 @Transactional 注释来达到此目的,但实际上我只能指定一个 txManager:

<tx:annotation-driven transaction-manager="manager"/>

摆脱这种情况的出路是什么?

I have 2 databases (MySql and HSQLDB). I configured 2 data sources and 2 EntityManagerFactory beans. I can also configure 2 correspondent JpaTransactionManager beans.

But I don't know how to specify which of them should be used to manage transactions for concrete service-class. I want to use @Transactional annotation for that purpose, but I actually can specify only one of txManagers:

<tx:annotation-driven transaction-manager="manager"/>

What is the way out from this situation?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夢归不見 2024-08-23 05:50:49

JpaTransactionManager 的 javadoc< /a> 对此有一些建议:

该事务管理器是
适用于使用的应用程序
单个 JPA EntityManagerFactory 用于
交易数据访问。日本旅游协会
(通常通过
JtaTransactionManager)是必要的
用于访问多个事务
同一事务中的资源。
请注意,您需要配置您的
JPA 提供者相应地为了
使其参与JTA
交易。

换句话说,如果您发现自己有多个实体管理器以及相应的 tx 管理器,那么您应该考虑使用单个 JtaTransactionManager 代替。实体管理器应该能够参与 JTA 事务,这将为您提供跨两个实体管理器的完整事务性,而不必担心您在任何时候处于哪个实体管理器中。

当然,JtaTransactionManager 确实需要一个完整支持 JTA 的应用程序服务器,而不是像 Tomcat 这样的普通 servlet 引擎。

The javadoc for JpaTransactionManager has some advice on this:

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.

In other words, if you find yourself with multiple entity managers, with corresponding tx managers, then you should consider using a single JtaTransactionManager instead. The entity managers should be able to participate in JTA transactions, and this will give you full transactionality across both entity managers, without hacving to worry about which entity manager you're in at any one time.

Of course, JtaTransactionManager does require a full JTA-supporting application server, rather than a vanilla servlet engine like Tomcat.

吾性傲以野 2024-08-23 05:50:49

声明不带 transaction-manager 属性的 ,为事务管理器声明限定符,如下所示:

<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <qualifier value="txManager1"/>
</bean>

@Transactional 中使用此限定符> 作为来选择事务管理器之一:

@Transactional("txManager1")

或者,具有更多属性:

@Transactional(value = "txManager1", readOnly = true)   

Declare your <tx:annotation-driven> without transaction-manager attribute, declare qualifiers for transaction managers like this:

<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
    <qualifier value="txManager1"/>
</bean>

Use this qualifier in @Transactional as a value to select one of transaction managers:

@Transactional("txManager1")

or, with more properties:

@Transactional(value = "txManager1", readOnly = true)   
小帐篷 2024-08-23 05:50:49

因为距离正确答案已经很长时间了。

Skaffman 在 JpaTransactionManager 对于多个数据库的可用性方面可能是正确的。

但是有一个工作解决方案可以使用 2 个不同的数据库和 2 个不同的 JpaTransactionManager。

  @Bean(name = "db2TransactionManager")
  public PlatformTransactionManager transactionManager2() throws NamingException {
    JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
    return txManager;
  }

  @Bean
  @Primary
  public PlatformTransactionManager transactionManager() throws Exception {
     JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
    txManager.setNestedTransactionAllowed(true);
    return txManager;
  }

@Primary 应用于指定在 @Transactional 中未指定限定符名称的情况

Since its after a longtime since the correct answers.

Skaffman may be correct in terms of usability of JpaTransactionManager for multiple databases.

But there is working solution for using 2 different databases with 2 different JpaTransactionManager.

  @Bean(name = "db2TransactionManager")
  public PlatformTransactionManager transactionManager2() throws NamingException {
    JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
    return txManager;
  }

  @Bean
  @Primary
  public PlatformTransactionManager transactionManager() throws Exception {
     JpaTransactionManager txManager = new JpaTransactionManager(entityManagerFactory());
    txManager.setNestedTransactionAllowed(true);
    return txManager;
  }

@Primary should be used to specify for the ones where you don't specify qualifier name in @Transactional

小清晰的声音 2024-08-23 05:50:49

您必须在 application-context.xml 中为其指定两个事务管理器,如下所示:

<tx:annotation-driven transaction-manager="manager1"/>
<tx:annotation-driven transaction-manager="manager2"/>

@Transactional 属性现在将使用其相关的事务管理器。

You have to specify two transaction managers for that in application-context.xml as below:

<tx:annotation-driven transaction-manager="manager1"/>
<tx:annotation-driven transaction-manager="manager2"/>

@Transactional attribute will now use its relevant transaction manager.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文