Java 如何配置事务管理以在 Spring 中使用 2 个不同的数据库?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1961566/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to configure transaction management for working with 2 different db in Spring?
提问by Roman
I have 2 databases (MySql and HSQLDB). I configured 2 data sources and 2 EntityManagerFactory beans. I can also configure 2 correspondent JpaTransactionManager beans.
我有 2 个数据库(MySql 和 HSQLDB)。我配置了 2 个数据源和 2 个 EntityManagerFactory bean。我还可以配置 2 个对应的 JpaTransactionManager bean。
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:
但我不知道如何指定它们中的哪些应该用于管理具体服务类的事务。我想为此使用@Transactional
注释,但实际上我只能指定 txManager 之一:
<tx:annotation-driven transaction-manager="manager"/>
What is the way out from this situation?
摆脱这种局面的出路是什么?
采纳答案by skaffman
The javadoc for JpaTransactionManagerhas some advice on this:
JpaTransactionManager的javadoc对此有一些建议:
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.
此事务管理器适用于使用单个 JPA EntityManagerFactory 进行事务数据访问的应用程序。JTA(通常通过 JtaTransactionManager)是访问同一个事务中的多个事务资源所必需的。请注意,您需要相应地配置 JPA 提供程序以使其参与 JTA 事务。
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.
换句话说,如果您发现自己有多个实体管理器,以及相应的 tx 管理器,那么您应该考虑使用单个实体管理器JtaTransactionManager
。实体管理器应该能够参与 JTA 事务,这将为您提供跨两个实体管理器的完整事务性,而无需担心您在任何时候都在哪个实体管理器中。
Of course, JtaTransactionManager
does require a full JTA-supporting application server, rather than a vanilla servlet engine like Tomcat.
当然,JtaTransactionManager
它需要一个完整的支持 JTA 的应用服务器,而不是像 Tomcat 这样的普通 servlet 引擎。
回答by axtavt
Declare your <tx:annotation-driven>
without transaction-managerattribute, declare qualifiers for transaction managers like this:
声明您<tx:annotation-driven>
没有事务管理器属性,为事务管理器声明限定符,如下所示:
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<qualifier value="txManager1"/>
</bean>
Use this qualifier in @Transactionalas a valueto select one of transaction managers:
在@Transactional 中使用此限定符作为值来选择事务管理器之一:
@Transactional("txManager1")
or, with more properties:
或者,具有更多属性:
@Transactional(value = "txManager1", readOnly = true)
回答by Mital Pritmani
You have to specify two transaction managers for that in application-context.xml as below:
您必须在 application-context.xml 中为此指定两个事务管理器,如下所示:
<tx:annotation-driven transaction-manager="manager1"/>
<tx:annotation-driven transaction-manager="manager2"/>
@Transactional attribute will now use its relevant transaction manager.
@Transactional 属性现在将使用其相关的事务管理器。
回答by raksja
Since its after a longtime since the correct answers.
由于它经过很长时间以来的正确答案。
Skaffman may be correct in terms of usability of JpaTransactionManager for multiple databases.
Skaffman 在 JpaTransactionManager 对多个数据库的可用性方面可能是正确的。
But there is working solution for using 2 different databases with 2 different 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
should be used to specify for the ones where you don't specify qualifier name in @Transactional
@Primary
应该用于指定您未在其中指定限定符名称的那些 @Transactional