Как настроить управление транзакциями для работы с 2 различными БД в Spring? - PullRequest
34 голосов
/ 25 декабря 2009

У меня есть 2 базы данных (MySql и HSQLDB). Я настроил 2 источника данных и 2 бина EntityManagerFactory. Я также могу настроить 2 соответствующих бина JpaTransactionManager.

Но я не знаю, как указать, какую из них следует использовать для управления транзакциями для конкретного класса обслуживания. Я хочу использовать аннотацию @Transactional для этой цели, но на самом деле я могу указать только один из txManager:

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

Какой выход из этой ситуации?

Ответы [ 4 ]

19 голосов
/ 25 декабря 2009

Объявите свой <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)   
18 голосов
/ 25 декабря 2009

Javadoc для JpaTransactionManager имеет несколько советов по этому поводу:

Этот менеджер транзакций подходит для приложений, которые используют один JPA EntityManagerFactory для доступ к транзакционным данным. JTA (обычно через JtaTransactionManager) необходимо для доступа к нескольким транзакциям ресурсы в рамках одной транзакции. Обратите внимание, что вам нужно настроить JPA провайдер соответственно для того, чтобы заставить его участвовать в JTA сделки.

Другими словами, если вы обнаружите, что у вас есть несколько менеджеров сущностей, с соответствующими менеджерами tx, тогда вам следует рассмотреть возможность использования одного JtaTransactionManager. Менеджеры сущностей должны иметь возможность участвовать в транзакциях JTA, и это обеспечит вам полную транзакционность между обоими менеджерами сущностей, не беспокоясь о том, какой менеджер сущностей вы находитесь в любое время.

Конечно, JtaTransactionManager требует полностью сервер приложений, поддерживающий JTA, а не ванильный движок сервлетов, такой как Tomcat.

12 голосов
/ 21 сентября 2013

С тех пор, как спустя много времени правильные ответы.

Скаффман может быть прав с точки зрения удобства использования 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

6 голосов
/ 21 октября 2011

Для этого необходимо указать два менеджера транзакций в application-context.xml, как показано ниже:

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

@ Атрибут транзакции теперь будет использовать соответствующий менеджер транзакций.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...