Spring обработка транзакций JMSTemplate внутри метода @Transactional - PullRequest
0 голосов
/ 20 декабря 2018

В нашем весеннем загрузочном приложении у нас есть пейджинговый цикл над базой данных, который будет отправлять JMS-сообщение для каждой страницы, используя JMSTemplate.Метод, содержащий цикл - @Transactional.JMSTemplate создается с установленным значением true для установленного флага.

Я просматривал исходный код JMSTemplate и, насколько я вижу, он не будет фиксировать сеанс, на который был произведен транзакции, если он уже существует.внешняя транзакция продолжается, но будет помещать ее в эту транзакцию.

Давайте теперь рассмотрим следующий код:

@Transactional
public void loopThroughPages(String destination, String from, String to) {
    Pageable pageRequest = PageRequest.of(0, maxPageSize);
    Page<Event> eventPage;
    do {
       eventPage = eventRepo.getEventsInTimeRangeForDestination(from, to, destination, pageRequest);
       if(eventPage.hasContent()) {
          Message<String> eventMessage = buildEventMessage(eventPage.getContent());
          JmsTemplate template = queueService.createTemplate(destination);
          template.send(eventMessage);
          pageRequest = eventPage.nextPageable();
       }
    } while(pageRequest != null && eventPage.hasNext());
}

createTemplate создает DynamicJmsTemplate, используя CachingConnectionFactory иsetSessionTransacted до true

Теперь я не совсем уверен, как это отразится на транзакциях.Насколько я понимаю, все сообщения страницы N отправляются в транзакции, созданной из loopThroughPages, и после завершения метода loopThroughPages он будет фиксировать все сообщения N, а не после отправки каждого сообщения.Это также означает, что транзакция на стороне MQ будет оставаться открытой до тех пор, пока не будет обработана последняя страница.Это понимание правильно?

1 Ответ

0 голосов
/ 20 декабря 2018

Ключевым моментом здесь является управление Трансацией.

Если вы используете источник данных XA и сконфигурируете его в своем приложении весенней загрузки, у вас будет распределенная транзакция, а принятие / откат для вашей транзакции будет осуществляться весной, поскольку у вас есть метод, аннотированный @Transactional, в противном случаеу вас будет локальное управление транзакциями, и транзакция вашей базы данных и системы обмена сообщениями не будет синхронизирована.

Для отправки сообщения вы можете в свойствах настроить, если сообщение сохраняется или нет, это означает, что ваши сообщения будутсохраняется вашей системой обмена сообщениями, а для слушателя вы можете настроить режим подтверждения.Между прочим, мой совет - дать возможность управлять транзакцией, и все будет хорошо, но реальное внимание следует обратить на то, что если вы хотите распределенную транзакцию между базой данных и системой jms, вам нужно только настроить ее, атомикос может быть доступной опцией, в противном случаедостаточно не управлять транзакцией вручную и позволить Spring управлять ею за вас.

Я надеюсь, что она может помочь вам

...