Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Синхронизировать JMS и JDBC транзакции, Апдэйт БД+отправка JMSсообщения 
V
    Опции темы
fitdnu2014
Дата 12.9.2014, 14:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 11.9.2014

Репутация: нет
Всего: нет



Добрый день всем! Хочу использовать ActiveMQ для отправки сообщения в очередь при изменении данных в БД (Sybase). Для управления транзакциями БД в приложении используется Spring DataSourceTransactionManager. Для отправки сообщений в очередь использую JmsTemplate. Проблема заключается в том, что нужно в рамках одной транзакции сделать примерно слюдующие действия:
Шаг 1: апдэйт БД;
Шаг 2: отправка сообщения в очередь;
Шаг 3: апдэйт БД;
Шаг 4: отправка сообщения в очередь.

Если на каком-то этапе возникает исключение - нужно откатить всю транзакцию целиком. Как я понял из документации по JmsTemplate, в моём случае я должен установить параметр "sessionTransacted" = true:
Цитата

Setting this flag to "true" will use a short local JMS transaction when running outside of a managed transaction, and a synchronized local JMS transaction in case of a managed transaction (other than an XA transaction) being present. The latter has the effect of a local JMS transaction being managed alongside the main transaction (which might be a native JDBC transaction), with the JMS transaction committing right after the main transaction.


Конфигурационный файл для JMS содержит только две секции:
Код


<bean id="connectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
        <property name="brokerURL" ref="url"/>
        <property name="userName" ref="username"/>
        <property name="password" ref="password"/>
</bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
        <property name="connectionFactory" ref="connectionFactory"/>
        <property name="defaultDestinationName" value="SomeQueue"/>
        <property name="sessionTransacted" value="true"/>
</bean>


Решил проверить работоспособность этого, кидая запросы на два простых метода, которые прикрутил к контроллеру:

Код

@Transactional
public void sendMessageTransactionalErr(Object message, List<String> queueDestinationNames) throws Exception {
    sender.sendMessage(message, queueDestinationNames);
    throw new Exception("FatalException!");
}


Код

@Transactional
public void sendMessageTransactionalOK(Object message, List<String> queueDestinationNames) throws Exception {
    sender.sendMessage(message, queueDestinationNames);
}


Но в обоих случаях сообщение попадает в очередь. Даже если возникает исключение (в методе sendMessageTransactionalErr), и происходит роллбэк транзакции JDBC, JMS-ная транзакция всё равно завершается успешно. Что я должен сделать, чтобы заставить эту схему работать так как мне нужно?

PM MAIL   Вверх
d_k
Дата 12.9.2014, 14:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 76
Регистрация: 20.7.2004

Репутация: 1
Всего: 1



ну во первых, чекед эксепшин не приведет к откату трензакции, если явно не прописан rollBackFor, а во вторых тут нужны нелокальные а глобальные транзакции, т.е. надо корректно сконфигурить менеджер транзакций, датасорс заменить на XA.
Но! С ActiveMq этого не выйдет, поскольку эта реализация jms не поддерживает глобальные транзакции...
PM MAIL   Вверх
fitdnu2014
Дата 12.9.2014, 16:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 11.9.2014

Репутация: нет
Всего: нет



Цитата(d_k @ 12.9.2014,  14:35)
ну во первых, чекед эксепшин не приведет к откату трензакции, если явно не прописан rollBackFor, а во вторых тут нужны нелокальные а глобальные транзакции, т.е. надо корректно сконфигурить менеджер транзакций, датасорс заменить на XA.
Но! С ActiveMq этого не выйдет, поскольку эта реализация jms не поддерживает глобальные транзакции...

Спасибо за наводку, совсем забыл уже, что контролируемые эксепшены не откатывают транзакцию. Удивительно, но после добавления
Код

@Transactional(rollbackFor = Exception.class)

сообщение в очередь не попадает smile

P.S.: Попробую потестировать ещё на более сложных примерах, позже отпишусь о результатах.
PM MAIL   Вверх
fitdnu2014
Дата 15.9.2014, 09:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 11.9.2014

Репутация: нет
Всего: нет



Протестировал более сложный вариант - апдэйт БД + отправка сообщения в цикле несколько раз, и затем пробросил исключение - транзакция откатилась и сообщения в очередь не попали. Причём когда закомментировал флаг "sessionTransacted" = true - соощебния попадают в очередь даже при откате транзакции. Так что вопрос можно считать решённым smile

Это сообщение отредактировал(а) fitdnu2014 - 15.9.2014, 10:09
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java EE (J2EE) и Spring | Следующая тема »


 




[ Время генерации скрипта: 0.0536 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.