In our spring boot application we have a paging loop over the database which will send a JMS message for every page using a JMSTemplate. The method containing the loop is @Transactional. The JMSTemplate is created with the transacted flag set to true.
I have been browsing through the source code of JMSTemplate and as far as I can see it will not commit a transacted session if there is already a outer transaction going on but will put it into that transaction.
Let's now consider the following code:
@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());
}
The createTemplate creates a DynamicJmsTemplate using a CachingConnectionFactory and setSessionTransacted to true
I am now not entirely sure how this translates to the transactions. My understanding is that all N page messages are sent in the transaction created from the loopThroughPages and once the loopThroughPages method finishes it will commit all N messages and not after each message has been sent. That also implies that the transaction on MQ side will stay open until the last page has been processed. Is this understanding correct?