Ответ 1
Эта статья может помочь Распределенные транзакции в Spring с XA и без нее. Я не думаю, что это касается вашего дела конкретно - отправки сообщения + обновления базы данных.
У меня есть веб-приложение spring, работающее на jboss, которое в настоящее время настроено на использование HibernateTransactionManager для транзакций db и JmsTransactionManager для jms. Для jms мы используем Camel и ActiveMQ, наша база данных - DB2. Внутри транзакции мне нужно записать несколько записей в базу данных и отправить два асинхронных сообщения jms. Сообщения jms представляют собой уведомления о событиях, и я хочу, чтобы они были отправлены, если транзакция базы данных совершается.
Я готов принять риск сообщения с брокерским сбоем после того, как транзакция jdbc уже совершена (и, следовательно, не отправлено сообщений, а db), поэтому я не думаю, что мне нужен правильный XA.
Я считаю, что мне нужно управление транзакциями "с наилучшими усилиями" с использованием транзакционной синхронизации spring.
Описание документации spring указывает на то, что spring синхронизирует две транзакции и совершает транзакцию jms только после того, как транзакция jdbc была совершена, но я не думаю, что это очень ясно. Документация spring здесь http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/transaction.html#tx-resource-synchronization не содержит подробных сведений о том, как она работает.
Я нашел несколько других источников, которые говорят, что spring будет делать то, что я хочу, включая некоторые javadoc ниже, и я написал некоторые интеграционные тесты, которые также показывают его.
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/jms/support/JmsAccessor.html#setSessionTransacted%28boolean%29 javadoc on setSessionTransacted здесь звучит точно так, как я хочу.
Из того, что я видел, я думаю, что создание Camel JmsConfiguration с транзакционным множеством в true, как это достаточно:
<bean id="jmsConfig" class="org.apache.camel.component.jms.JmsConfiguration">
<property name="connectionFactory" ref="pooledConnectionFactory"/>
<property name="transacted" value="true"/>
<property name="concurrentConsumers" value="10"/>
</bean>
Однако мне нужно убедить кого-то, с кем я работаю, с немного скептически настроенным и думает, что мой интеграционный тест работает только из-за плохо документированного побочного эффекта, а не для намеренной функции spring.
Итак, мой вопрос: я исправлю, что на spring можно полагаться на синхронизацию транзакций и всегда фиксировать транзакцию jms после транзакции jdbc или это не то, на что я должен положиться, и вы могли бы указать мне на любая официальная документация, которая гласит это четко? И я предполагаю, что в целом это хороший подход для принятия или должен управлять этими транзакциями по-другому?
Эта статья может помочь Распределенные транзакции в Spring с XA и без нее. Я не думаю, что это касается вашего дела конкретно - отправки сообщения + обновления базы данных.
Официальный Spring Загрузочный репозиторий содержит примеры JTA, которые объединяют JMS с JDBC на основе Atomikos, Bitronix или Java EE-сервер JBoss WildFly.
Кроме того, я также создал несколько примеров расположенных в моем репозитории Github. Это также содержит пример Spring Boot (чистый Spring).
Если вы используете локальные транзакции И usecase - это сохранить в базу данных, а затем отправить в jms
Тогда могут быть три случая:
Без проблем все будет откатываться
Если есть операция вставки, в результате повторных попыток будет выполняться несколько строк в БД. С каждой попыткой будет выполнена вставка. И для JMS сообщение перейдет в DeadLetterQueue
Если есть операция вставки, в результате повторных попыток будет выполняться несколько строк в БД. С каждой попыткой будет выполнена вставка. И для JMS сообщение перейдет в DeadLetterQueue
Теперь вы не хотите использовать XA, поэтому решения могут быть
1) Проверьте If (message.getJmsRedelivered() {...}
Если нет, обработайте его
Если его переадресовано, проверьте, обработали ли вы его уже
Проверьте, находятся ли данные в базе данных на основе сведений в сообщении
Обратите внимание, что повторные поставки редки, поэтому эта проверка также редка и нет накладных расходов
2) Если ваш метод идемпотент, вам не нужна эта проверка
И что касается XA, XA гарантирует, что сообщение доставляется только один раз И синхронизировать транзакцию через несколько ресурсов.
Но с XA у вас есть служебные
Итак, если вы можете обойтись без XA, предпочтительнее