У меня есть один файл 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 говорится:
This transaction manager is appropriate for applications that use a single JPA EntityManagerFactory for transactional data access. JTA (usually through JtaTransactionManager) is necessary for accessing multiple transactional resources within the same transaction. Note that you need to configure your JPA provider accordingly in order to make it participate in JTA transactions.
Это означает, что вам нужно будет предоставить диспетчер транзакций 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, а не реализацию JPA Hibernate. В этом случае мы смогли избавиться от двух bean-компонентов HibernateTransactionManager и просто убедиться, что в оба SessionFactories был внедрен один и тот же JTA TM, а затем использовать элемент tx:, управляемый аннотациями.
Надеюсь это поможет
Единственная ситуация, в которой у вас может быть два менеджера транзакций Spring, - это если у вас никогда не открываются обе транзакции одновременно. По сути, это не связано с распределенными транзакциями - те же ограничения применяются, даже если вы хотите, чтобы два источника данных имели полностью отдельные (но потенциально перекрывающиеся во времени) жизненные циклы транзакций.
Внутри все менеджеры транзакций Spring используют Spring TransactionSynchronizationManager, который хранит кучу критического состояния в статических переменных ThreadLocal, поэтому менеджеры транзакций гарантированно перебирают все состояния друг друга.
Можете ли вы предоставить образец кода или POC jtaTransaction с несколькими базами данных?