1

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

如果我设置,在 PL/SQL 中一切都很好并且可以工作

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

在出队。

入队选项相应地设置为 IMMEDIATE 和 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);

我没有在出队/接收方的事务中运行。如何在 JMS 中设置“可见性”?任何想法为什么我没有收到消息?

我错过了什么?

Payload 是 sys.AQ$_JMS_TEXT_MESSAGE,非压缩等。

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

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

4

2 回答 2

1

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

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

      receiver.bufferReceive(timeout);

代替

      receiver.receive(timeout);

只有在 Oracle JMS 代码中进行调试才能将我们带到这个解决方案。网上关于这方面的文档很差。

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

于 2020-02-12T16:35:56.467 回答
1

JMS 规范 (JSR 914) 定义了两种交付模式:PERSISTENTNON_PERSISTENT. 对于 Oracle,这些模式是PERSISTENTBUFFERED

但是,Oracles JMS 实现似乎只接收PERSISTENT默认情况下的那些。

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

正如您自己所说,QueueReceiver可以将其转换为 aAQjmsConsumer以处理缓冲消息。

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

发送缓冲消息时也是如此。在这里,QueueSender必须将其转换为 aAQjmsProducer以获得手头缓冲消息的方法:

AQjmsProducer producer = (AQjmsProducer)session.createProducer(queue);
producer.bufferSend(queue, msg, priority, timeToLive);
于 2020-02-13T08:01:42.193 回答