Spring @Transactional 方法中的事务处理 JMSTemplate
Spring transaction handling JMSTemplate inside @Transactional method
在我们的 spring 引导应用程序中,我们在数据库上有一个分页循环,它将使用 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
使用 CachingConnectionFactory
和 setSessionTransacted
创建 DynamicJmsTemplate
到 true
我现在不完全确定这如何转化为交易。我的理解是,所有 N
页面消息都在从 loopThroughPages
创建的事务中发送,一旦 loopThroughPages
方法完成,它将提交所有 N
消息,而不是在每条消息之后已经发送。这也意味着 MQ 端的事务将保持打开状态,直到处理完最后一页。这个理解对吗?
这里的重点是交易管理。
如果您使用 XA 数据源并在您的 spring 启动应用程序上配置它,您将拥有一个分布式事务,并且您的事务的 commit/rollback 将由 spring 管理,因为那你有一个用@Transactional 注释的方法,否则你将有一个本地事务管理,并且你的数据库和消息系统的事务将不会同步。
对于发送消息,您可以通过属性配置消息是否持久化,这意味着您的消息是否会被您的消息传递系统持久化,而从听众的角度来看,您可以配置确认模式。
顺便说一下,我的建议是 spring 管理事务,一切都会好起来的,但真正要注意的是,如果你想要数据库和 jms 系统之间的分布式事务,你只需要配置它 atomikos 就可以了选项,否则就足够了,不要手动管理事务,让 Spring 为您管理。
希望对您有所帮助
在我们的 spring 引导应用程序中,我们在数据库上有一个分页循环,它将使用 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
使用 CachingConnectionFactory
和 setSessionTransacted
创建 DynamicJmsTemplate
到 true
我现在不完全确定这如何转化为交易。我的理解是,所有 N
页面消息都在从 loopThroughPages
创建的事务中发送,一旦 loopThroughPages
方法完成,它将提交所有 N
消息,而不是在每条消息之后已经发送。这也意味着 MQ 端的事务将保持打开状态,直到处理完最后一页。这个理解对吗?
这里的重点是交易管理。
如果您使用 XA 数据源并在您的 spring 启动应用程序上配置它,您将拥有一个分布式事务,并且您的事务的 commit/rollback 将由 spring 管理,因为那你有一个用@Transactional 注释的方法,否则你将有一个本地事务管理,并且你的数据库和消息系统的事务将不会同步。
对于发送消息,您可以通过属性配置消息是否持久化,这意味着您的消息是否会被您的消息传递系统持久化,而从听众的角度来看,您可以配置确认模式。 顺便说一下,我的建议是 spring 管理事务,一切都会好起来的,但真正要注意的是,如果你想要数据库和 jms 系统之间的分布式事务,你只需要配置它 atomikos 就可以了选项,否则就足够了,不要手动管理事务,让 Spring 为您管理。
希望对您有所帮助