2008-09-16 2 views
11

У меня есть один файл applicationContext.xml, и у него есть два org.springframework.orm.jpa.JpaTransactionManager (каждый со своей собственной единицей непрерывности, разные базы данных), настроенные в пользовательском приложении промежуточного промежуточного слоя.

Я хочу использовать транзакции на основе аннотаций (@Transactional), чтобы не вмешиваться в транзакцию, сохранение и откат транзакции TransactionStatus.

Коллега упомянул, что-то путается делает это, когда есть несколько менеджеров транзакций, даже если файл контекст установлен правильно настроены (ссылки идут на правильный блок сохранения. Кто-нибудь увидеть проблему?JPA Несколько менеджеров транзакций


В вашей конфигурации, что у вас есть два менеджера транзакций? вы бы txManager1 и txManager2?

Вот что я с JPA, две различные пружинные бобы, которые являются менеджеры транзакций.

ответ

9

Я предполагаю, что у вас есть 2 варианта

Если ваши прецеденты никогда не требуют обновлений для обеих баз данных в рамках одной и той же транзакции, тогда вы можете использовать два JpaTransactionManagers, но я не уверен, что вы сможете использовать подход @Transactional ? В этом случае вам нужно будет Откат на старом механизме с помощью простого TransactionProxyFactoryBean для определения границ транзакций, например:

<bean id="firstRealService" class="com.acme.FirstServiceImpl"/> 
<bean id="firstService" 
    class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> 
    <property name="transactionManager" ref="firstJpaTm"/> 
    <property name="target" ref="firstRealService"/> 
    <property name="transactionAttributes"> 
     <props> 
      <prop key="insert*">PROPAGATION_REQUIRED</prop> 
      <prop key="update*">PROPAGATION_REQUIRED</prop> 
      <prop key="*">PROPAGATION_REQUIRED,readOnly</prop> 
     </props> 
    </property> 
</bean> 
<!-- similar for your second service --> 

Если вы требуете сделок, охватывающими обе базы данных, то вам необходимо будет использовать JTA менеджер транзакций. В API указывается:

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

Это означает, что вам необходимо предоставить менеджера транзакций JTA. В нашем приложении мы используем конфигурации, подобные следующему:

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

<bean id="txManager" 
    class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManagerName" value="appserver/jndi/path" /> 
</bean> 

При развертывании внутри сервера приложений, то весной JtaTransactionManager должен сделать поиск в реальном XA-совместимого менеджер транзакций JTA, предоставленный AppServer. Тем не менее, вы также можете использовать автономный менеджер транзакций JTA (но я еще не пробовал это сам)

Что касается настройки поставщика непрерывности Jpa, я не так привык. Какой провайдер постоянства JPA вы используете?

Приведенный выше код основан на нашем подходе, в котором мы использовали родной Hibernate, а не JPA-реализацию Hibernate. В этом случае нам удалось избавиться от двух бобин HibernateTransactionManager и просто убедиться, что обе SessionFactories были введены с тем же JTA TM, а затем используют элемент, управляемый аннотациями tx:.

Надеется, что это помогает

+0

может предоставить пример кода или POC jtaTransaction с несколькими базами данных? – dhroove 2013-05-21 09:08:41

3

Единственной ситуация, в которой вы можете иметь два менеджера транзакций Spring, если вы никогда не иметь оба транзакций открытых в одно времени.Это не внутренне связано с распределенными транзакциями - те же ограничения применяются, даже если вы хотите, чтобы два источника данных имели полностью отдельные (но потенциально перекрывающиеся во времени) жизненные циклы транзакций.

Операторы транзакций Internally Spring все используют TransactionSynchronizationManager от Spring, который хранит кучу критического состояния в статических переменных ThreadLocal, поэтому менеджеры транзакций гарантированно будут топать по всему состоянию друг друга.

Смежные вопросы