当前位置: 首页 > 知识库问答 >
问题:

@JmsListener和持久化到数据库

郎雅昶
2023-03-14

我正在开发一个服务,在该服务中,我侦听队列,反序列化接收到的消息,并将它们持久化到数据库(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中,我设置并发性和setSessionTransactived(true)。这足以使整个onMessage具有事务性吗?因此,在一个事务中接收并保存一条消息,并在其中任何一点出现故障时回滚?当试图保存特定消息时,我尝试对其抛出异常,消息确实被回滚到队列,侦听器再次尝试使用它们,这是一种理想的行为。在研究这个问题时,我偶然发现了分布式事务,即jta事务管理器,但我仍然不确定除了SetSessionTransact(true)之外是否还需要配置更多事务,或者Spring Boot是否自动处理XA资源的事务。寻求建议。非常感谢。

共有1个答案

孔驰
2023-03-14

如果您的侦听器的onMessage()正在与事务性资源交互,而不是从JMS代理接收消息,那么调用setSessionTransactived(true)不足以使所有交互都是事务性的。

JMS中的“事务化”会话仅涵盖该特定会话的JMS操作。它不包括使用任何其他事务性资源(例如数据库)的工作。

如果您想要一个涉及监听器对消息的使用以及监听器所做的任何其他事务工作(例如,更新或插入数据库中的记录,向另一个代理发送JMS消息等)的事务,那么您需要一个JTA事务管理器,它可以与XA资源一起工作,以协调各个事务阶段(例如,准备、提交、回滚)。这些类型的事务有时称为“分布式”事务。

这是一个相当常见的用例,因为它将JMS消息转换为一种“工作单元”,您知道如果消息被使用,那么与该消息相关的所有工作也会成功完成,反之亦然。这是MDB在Java EE中提供的主要内容之一,但同样的重要工作也可以在Spring中完成。

根据Spring Boot文档,您可以与一些不同的事务管理器(例如Atomikos、Bitronix、Narayana等)集成来完成这类工作。

需要明确的是,在某些情况下,您现有的安排将以这样一种方式工作,使这两个操作看起来是在同一事务中。例如,如果您的数据库操作引发异常,并且该异常是从onMessage()引发的,则消息将回滚到队列中。然而,在这种情况下,这两个操作只是相互关联的。它们不在同一事务中,因此它们实际上不会是原子的。相反,如果数据库操作成功,然后由于某种原因,监听器的onMessage()引发了另一个异常,或者JMS代理在提交事务会话之前崩溃,那么消息最终将回滚到队列中,但数据也将仍然在数据库中,这样,如果再次使用消息,表面上就可以编写将相同的数据再次发送到数据库。

 类似资料:
  • 我正在使用网络逻辑10.3。我正在尝试配置一个持久订阅,其中包含由 jdbc 存储(在 Oracle DB 中)支持的持久消息。我有一个主题,MDB 正在作为持久订阅者侦听该主题。在场景-1下:如果我发送消息,它会命中MDB。 在场景2中:我挂起了MDB,希望发送到主题的消息只要不被MDB(它是唯一注册的持久订阅者)使用,就会一直存在。但是当我向主题发送消息时,它短暂地出现在那里,然后就消失了(我

  • 数据落盘问题的由来 这本质上是数据持久化问题,对于有些应用依赖持久化数据,比如应用自身产生的日志需要持久化存储的情况,需要保证容器里的数据不丢失,在Pod挂掉后,其他应用依然可以访问到这些数据,因此我们需要将数据持久化存储起来。 数据落盘问题解决方案 下面以一个应用的日志收集为例,该日志需要持久化收集到ElasticSearch集群中,如果不考虑数据丢失的情形,可以直接使用前面提到的应用日志收集一

  • 为了学习数据的持久化,写一个简单的地址薄合约.虽然这个例子因为各种原因作为生产环境的合约不太实用,但它是一个很好的合约用来学习EOSIO的数据持久化并且不会因为与eosio multi_index不相关的相关业务逻辑分心. Step 1:创建一个新的文件夹 进入之前的目录: cd /Users/zhong/coding/CLion/contracts 为我们的合约创建一个新的目录并进去: mkd

  • 主要内容:一、数据持久化,二、持久化的形式,三、源码分析,四、总结一、数据持久化 redis做为一种内存型数据库,做持久化,个人感觉略有鸡肋的意思。似乎有一种,别人有,自己不有也不行的感觉。以目前Redis主流的应用方式,如果仔细分析,基本上都是在内存中即可完成,对持久化没要求或者说不大。再举一个反例,如果内存中有几百G甚至更多的数据,真要是整体当机,恢复的时间基本就是灾难。 目前基本应用仍然是以关系型数据库或者其它数据库(如Hadoop,Mysql等)为持久化

  • 目的 配置 NFS 共享为 OpenShift 节点提供存储,并且配置 OpenShift 持久卷以绑定至数据库 Pod。 环境 openshift v3.11.16/kubernetes v1.11.0 步骤 配置 NFS 共享持久卷1. 登录到 NFS 服务器 # ssh nfs.example.com2. 创建 config-nfs.sh 脚本,内容如下 #!/usr/bin/sh exp

  • 问题内容: 我想创建一个作业,但是我想在没有任何数据库持久性的情况下运行它。不幸的是,spring-batch要求以某种方式将作业周期写入数据库,从而迫使我至少提供某种带有transactionmanager和Entitymanager的数据库。 是否可以防止元数据并独立于txmanagers和数据库运行? 更新: 问题答案: 我回到我自己的问题上,因为该解决方案不再起作用。从spring-bat