我有两个数据库(MySql和HSQLDB)。我配置了两个数据源和两个EntityManagerFactory bean。我还可以配置两个对应的JpaTransactionManager bean。
但是我不知道如何指定哪一个应该用于管理具体服务类的事务。我想使用@Transactional
注释来实现这个目的,但我只能指定其中一个txManager:
<tx:annotation-driven transaction-manager="manager"/>
如何走出这种境地?
我有两个数据库(MySql和HSQLDB)。我配置了两个数据源和两个EntityManagerFactory bean。我还可以配置两个对应的JpaTransactionManager bean。
但是我不知道如何指定哪一个应该用于管理具体服务类的事务。我想使用@Transactional
注释来实现这个目的,但我只能指定其中一个txManager:
<tx:annotation-driven transaction-manager="manager"/>
如何走出这种境地?
声明您的<tx:annotation-driven>
时不要使用transaction-manager属性,像这样为事务管理器声明限定符:
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory" />
<qualifier value="txManager1"/>
</bean>
在@Transactional中使用这个限定符作为value,以选择其中一个事务管理器:
@Transactional("txManager1")
或者,带有更多属性:@Transactional(value = "txManager1", readOnly = true)
JpaTransactionManager的javadoc给出了一些建议:
这个事务管理器适用于使用单个JPA EntityManagerFactory进行事务数据访问的应用程序。在同一事务中访问多个事务资源时,需要使用JTA(通常通过JtaTransactionManager)。请注意,您需要相应地配置JPA提供程序,以便使其参与JTA事务。
换句话说,如果您有多个实体管理器,并且对应有多个tx管理器,则应考虑改用单个JtaTransactionManager
。实体管理器应能够参与JTA事务,这将使您在两个实体管理器之间获得完整的事务性,而无需担心当前所在的实体管理器。
当然,JtaTransactionManager
需要完全支持JTA的应用服务器,而不是像Tomcat这样的普通servlet引擎。
自从正确答案以来已经有很长时间了。
在使用JpaTransactionManager管理多个数据库方面,Skaffman的可用性可能是正确的。
但是,对于使用两个不同的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
中不指定限定符名称的情况下。
您需要在application-context.xml文件中指定两个事务管理器如下:
<tx:annotation-driven transaction-manager="manager1"/>
<tx:annotation-driven transaction-manager="manager2"/>
@Transactional属性现在将使用其相关的事务管理器。
tx:annotation-driven
的 AnnotationDrivenBeanDefinitionParser
,所有操作都只在每个上下文中执行一次!因此第二行完全没有用。 - Arne Burmeister