Вопрос

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

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

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


Будет ли в вашей конфигурации два менеджера транзакций?У вас есть txManager1 и txManager2?

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

Это было полезно?

Решение

Я думаю, у тебя есть 2 варианта

Если ваши сценарии использования никогда не требуют обновления обеих баз данных в рамках одной транзакции, вы можете использовать два JpaTransactionManager, но я не уверен, что вы сможете использовать подход @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>

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

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

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

Надеюсь это поможет

Другие советы

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top