Spring AMQP / RabbitMQ и менеджер транзакций Hibernate

У меня есть приложение Spring, использующее Hibernate и PostgreSQL. Он также использует Spring AMQP (RabbitMQ).

Я использую диспетчер транзакций Hibernate, настроенный следующим образом:

<bean id="transactionManager"
    class="org.springframework.orm.hibernate3.HibernateTransactionManager"
    p:sessionFactory-ref="sessionFactory" p:dataSource-ref="dataSource" />

Я использую SimpleMessageListenerContainer для приема асинхронных сообщений, настроенный как:

@Resource(name="transactionManager")
private PlatformTransactionManager txManager;

@Autowired
private MyListener messageListener;

@Bean
public SimpleMessageListenerContainer mySMLC()
{
    final SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
    container.setConnectionFactory(rabbitConnectionFactory);
    container.setQueueNames("myQueue");

    final MessageListenerAdapter adapter = new MessageListenerAdapter(messageListener);
    adapter.setMessageConverter(converter);
    container.setMessageListener(adapter);
    container.setChannelTransacted(true);
    container.setTransactionManager(txManager);
    return container;
}

Итак, в основном я указал, что получение сообщений должно быть транзакционным. Слушатель сообщений вызывает службу, которая может иметь методы, аннотированные с помощью @Transactional, и, возможно, выполнять операции CRUD с БД.

Мой вопрос: есть ли проблема с использованием HibernateTransactionManager для управления транзакцией на уровне SimpleMessageListenerContainer? Возникнут ли проблемы с использованием диспетчера транзакций БД для переноса сообщений от RabbitMQ?

Я не жду здесь XA. Я просто хочу убедиться, что в случае сбоя каких-либо операций с БД службой сообщение не будет отправлено брокеру RabbitMQ.


person CAL5101    schedule 28.06.2012    source источник


Ответы (1)


Согласно источникам Spring, основной целью свойства transactionManager MessageListenerContainer является запуск транзакции в сообщении, полученном до вызова слушателя, и фиксация или откат транзакции после того, как слушатель возвращает или генерирует исключение. Таким образом, нет необходимости создавать методы прослушивателя @Transactional, поскольку транзакция будет уже запущена до вызова метода прослушивателя.

В случае ошибки в прослушивателе будет сгенерировано исключение, транзакция БД откатится, и брокеру сообщений не будет отправлено подтверждение (откат транзакции jms). Но без XA могут быть повторяющиеся сообщения. Например, после успешной фиксации транзакции БД соединение с брокером сообщений сбрасывается, и брокеру не может быть отправлено подтверждение. После переподключения брокер мог доставить дублирующееся сообщение. Если вы признаете это, то с XA разбираться незачем.

person vp8106    schedule 15.09.2014