使用 JMS 从 AQ 队列中取出 Non_Persistent 消息

Dequeue Non_Persistent message from AQ Queue using JMS

我想从 Oracle AQ 队列中取出非持久(=缓冲)JMS 消息。

在 PL/SQL 中一切正常,如果我设置

L_DequeueOptions.VISIBILITY    := DBMS_AQ.IMMEDIATE;
L_DequeueOptions.DELIVERY_MODE := DBMS_AQ.BUFFERED;

关于出列器。

排队选项相应地设置为立即和缓冲。

尽管如此,在 Java 代码中,我尝试使用 javax.jms.QueueReceiver 使用 JMS 接收消息

QueueReceiver receiver = session.createReceiver(queue, "JMSDeliveryMode = 'PERSISTENT' or JMSDeliveryMode = 'NON_PERSISTENT'");
// and later on:
Message m = receiver.receive(conf.dequeueTimeout);

我不在 运行 的 dequeuer/receiver 交易中。 如何在 JMS 中设置 "visibility"? 为什么我收不到消息有什么想法吗?

我错过了什么?

有效载荷为 sys.AQ$_JMS_TEXT_MESSAGE,未压缩等。

顺便说一句:出列应用程序正在使用持久消息工作...

更新:如果我使用 MessageSelector,代码也不适用于持久消息。没有消息选择器和持久消息,它可以工作!

我们发现了如何管理它。 无法直接在 JMS 上使非持久性消息出列。我怀疑非持久性出队是标准的一部分。

唯一的方法是将 QueueReceiver 转换为 oracle.jms.AQjmsConsumer,然后调用

      receiver.bufferReceive(timeout);

而不是

      receiver.receive(timeout);

只有在 Oracle JMS 代码中调试才能让我们找到这个解决方案。 网上关于此的文档很差。

顺便说一句:消息选择器把我引向了完全错误的方向。

JMS 规范 (JSR 914) 定义了两种传递模式:PERSISTENTNON_PERSISTENT。关于 Oracle,这些模式是 PERSISTENTBUFFERED

但是,Oracles JMS 实现似乎默认只接收 PERSISTENT 个。

消息选择器本身由 Oracle 实现检查,但似乎对传递模式没有影响。

如您所说,QueueReceiver 可以转换为 AQjmsConsumer 来处理缓冲消息。

AQjmsConsumer consumer = (AQjmsConsumer)session.createReceiver(queue);
consumer.bufferReceive(dequeueTimeout);

发送缓冲消息时也是如此。这里必须将 QueueSender 强制转换为 AQjmsProducer 才能获得用于缓冲消息的方法:

AQjmsProducer producer = (AQjmsProducer)session.createProducer(queue);
producer.bufferSend(queue, msg, priority, timeToLive);