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



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

在 PL/SQL 中,如果我设置

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

在取消排队器上。

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

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

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

我没有在取消队列器/接收方的事务中运行。 如何在 JMS 中设置"可见性"? 知道为什么我没有收到消息吗?

我错过了什么?

有效载荷是系统。AQ$_JMS_TEXT_MESSAGE,非压缩等。

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

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

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

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

receiver.bufferReceive(timeout);

而不是

receiver.receive(timeout);

只有使用 Oracle JMS 代码进行调试才能让我们找到这个解决方案。 网络上关于这方面的文档很差。

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

JMS 规范 (JSR 914( 定义了两种交付模式:PERSISTENTNON_PERSISTENT。关于甲骨文,这些模式是PERSISTENTBUFFERED

但是,似乎 Oracle 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);

最新更新