我想从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,该代码也不适用于持久消息。如果没有消息选择器和持久消息,它将起作用!
答案 0 :(得分:1)
我们发现了如何进行管理。 直接在JMS上,无法使非持久消息出队。我怀疑非持久出队是否是标准的一部分。
唯一的方法是将QueueReceiver强制转换为oracle.jms.AQjmsConsumer
,然后调用
receiver.bufferReceive(timeout);
代替
receiver.receive(timeout);
只有使用Oracle JMS代码进行调试才能将我们带到该解决方案。 网络上关于此的文献不多。
顺便说一句:消息选择器将我引向完全错误的方向。
答案 1 :(得分:1)
JMS规范(JSR 914)定义了两种交付方式:PERSISTENT
和NON_PERSISTENT
。对于Oracle,这些模式为PERSISTENT
和BUFFERED
。
但是,似乎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);