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

时间:2020-02-12 06:52:04

标签: java oracle queue jms buffered

我想从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中设置“可见性”? 有什么想法为什么我没有收到消息?

我想念什么?

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

btw:出队的应用程序正在使用持久消息工作...

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

2 个答案:

答案 0 :(得分:1)

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

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

      receiver.bufferReceive(timeout);

代替

      receiver.receive(timeout);

只有使用Oracle JMS代码进行调试才能将我们带到该解决方案。 网络上关于此的文献不多。

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

答案 1 :(得分:1)

JMS规范(JSR 914)定义了两种交付方式:PERSISTENTNON_PERSISTENT。对于Oracle,这些模式为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);
相关问题