gpt4 book ai didi

spring-boot - @JmsListener 并持久化到数据库

转载 作者:行者123 更新时间:2023-12-04 03:53:00 26 4
gpt4 key购买 nike

我正在开发一项服务,在该服务中我监听队列、反序列化接收到的消息并将它们保存到数据库 (Oracle)。大致:

@JmsListener(destination="some-destination")
public void onMessage(Message message) throws Exception {
String message = ((TextMessage) message).getText();
service.save(deserialize(message));
// includes exception handling etc
}
在默认的消息监听器 bean 中,我设置了并发性和 setSessionTransacted(true) .这足以使整个 onMessage 具有事务性吗?以便在一个事务中接收并保存一条消息,并在其中任何一点出现故障时回滚?
当尝试保存特定消息时,我尝试在特定消息上抛出异常 - 消息确实回滚到队列中,并且监听器尝试再次使用它们,这是一种期望的行为。
在研究这个的时候,我偶然发现了分布式事务,jta事务管理器,但我仍然不确定除了setSessionTransacted(true)之外是否还需要配置更多,或者Spring Boot是否自动处理XA资源的事务。
寻求建议。谢谢你。

最佳答案

如果您的听众的 onMessage()除了调用 setSessionTransacted(true) 之外,它正在与接收消息的 JMS 代理以外的事务资源进行交互。是 不是 足以使所有交互成为事务性的。
JMS 中的“事务处理” session 仅涵盖具有该特定 session 的 JMS 操作。它不包括使用任何其他事务资源(例如数据库)的工作。
如果您想要一个涉及监听器消费消息的事务以及监听器完成的任何其他事务性工作(例如,在数据库中更新或插入记录、将 JMS 消息发送到另一个代理等),那么您需要一个 JTA事务管理器可以与 XA 资源一起工作以协调各种事务阶段(例如准备、提交、回滚)。这些类型的事务有时称为“分布式”事务。
这是一个相当常见的用例,因为它使 JMS 消息成为一种“工作单元”,并且您知道如果消息被使用,则与该消息相关的所有工作也已成功完成,反之亦然。这是 MDB 在 Java EE 中提供的主要功能之一,但同样的基本工作也可以在 Spring 中完成。
根据Spring Boot documentation您可以与少数不同的事务管理器(例如 Atomikos、Bitronix、Narayana 等)集成来完成此类工作。
需要明确的是,在某些情况下,您现有的安排会使两个操作看起来像是在同一个事务中。例如,如果您的数据库操作抛出异常,而该异常是从 onMessage() 抛出的。然后消息将回滚到队列中。然而,在这种情况下,这两个操作只是相关的。它们不在同一个事务中,因此它们实际上不是原子的。如果数据库操作成功了,然后由于某种原因从监听器的 onMessage() 抛出另一个异常。或者 JMS 代理在事务 session 可以提交之前崩溃,那么消息最终将回滚到队列中,但数据仍将在数据库中,因此如果您再次使用该消息,您表面上会写入相同的数据再次数据库。

关于spring-boot - @JmsListener 并持久化到数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64174065/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com