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

时间:2009-12-25 17:36:09

标签: java spring jpa transactions multiple-databases

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

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

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

出现这种情况的方法是什么?

4 个答案:

答案 0 :(得分:19)

声明您的<tx:annotation-driven>没有事务管理器属性,为事务管理器声明限定符,如下所示:

<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)   

答案 1 :(得分:17)

javadoc for JpaTransactionManager对此有一些建议:

  

这个交易经理是   适合使用的应用程序   一个JPA EntityManagerFactory for   交易数据访问。 JTA   (通常是通过   JtaTransactionManager)是必要的   用于访问多个事务   同一交易中的资源。   请注意,您需要配置您的   相应的JPA提供商为了   让它参加JTA   交易。

换句话说,如果您发现自己有多个实体经理,并且有相应的tx经理,那么您应该考虑使用单个JtaTransactionManager。实体经理应该能够参与JTA交易,这将为您提供跨两个实体经理的完全交易,而不必担心您在任何时候都在哪个实体经理。

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

答案 2 :(得分:11)

自从经过长时间的正确回答以后。

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

中未指定限定符名称的那些

答案 3 :(得分:6)

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

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

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