Spring事务在@Transactional方法中处理JMSTemplate

时间:2018-12-20 07:56:31

标签: java spring transactions jms

在我们的Spring Boot应用程序中,我们在数据库上有一个分页循环,它将使用JMSTemplate为每个页面发送一个JMS消息。包含循环的方法是@TransactionalJMSTemplate是在交易标记设为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使用DynamicJmsTemplateCachingConnectionFactorysetSessionTransacted来创建true

我现在不完全确定这将如何转换为交易。我的理解是,所有N页消息都是通过loopThroughPages创建的事务发送的,一旦loopThroughPages方法完成,它将提交所有N条消息,而不是在每条消息之后已经发送了。这也意味着MQ端的事务将保持打开状态,直到处理完最后一页为止。这种理解正确吗?

1 个答案:

答案 0 :(得分:1)

这里的关键是转移管理。

如果您使用XA数据源并在spring boot应用程序上对其进行配置,则将有一个分布式事务,并且事务的提交/回滚将由spring管理,因为您有一个带有@Transactional注释的方法,否则您将拥有本地事务管理,并且数据库和消息传递系统的事务将不同步。

对于发送消息,您可以通过属性配置消息是否持久化,这意味着消息系统是否可以持久化消息,而对于侦听器而言,您可以配置确认模式。 顺便说一下,我的建议是让弹簧管理事务,但一切都会很好,但是真正的注意点是,如果您想要在数据库和jms系统之间进行分布式事务,则只需配置它即可,atomikos可以是一个可用的选项,否则无需手动管理交易就足够了,让Spring来为您管理。

我希望它能为您提供帮助