在我们的Spring Boot应用程序中,我们对数据库进行了分页循环,每一页都使用
我一直在浏览
现在让我们考虑以下代码:
我现在不太确定这与事务有何关系。我的理解是所有的
JMSTemplate
发送一个JMS消息。包含该循环的方法是@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 上的事务将保持打开状态,直到处理完最后一页。这种理解正确吗?
JmsTemplate
中commit
和close
的评论,因为它不一定会关闭获取到的Session
,只有在无法从ConnectionFactoryUtils.doGetTransactionalSession
获取事务性会话时才会关闭。 - Yanick Salzmann