1

I would like to dequeue a non persistent (=buffered) JMS Message from an Oracle AQ queue.

In PL/SQL everything is fine and works, if I set

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

on the dequeuer.

The enqueuer options are set accordingly to IMMEDIATE and BUFFERED.

Nevertheless in Java Code I try to receive the message using JMS with a javax.jms.QueueReceiver using

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

I'm not running in a transaction on the dequeuer/receiver side. How can I set the "visibility" in JMS? Any ideas why I do not receive the messages?

What am I missing?

Payload is sys.AQ$_JMS_TEXT_MESSAGE, non compressed or the like.

btw: the dequeuing application is working using persistent messages...

Update: the code does not work for persistent messages also, if I use the MessageSelector. Without message selector and persistent messages it works!

Thirdman
  • 621
  • 7
  • 13

2 Answers2

1

We found out, how to manage this. Directly on JMS there is no way to dequeue non-persistent messages. I doubt that non-persistent dequeuing is part of the standard.

The only way is to cast the QueueReceiver to an oracle.jms.AQjmsConsumer and then call

      receiver.bufferReceive(timeout);

instead of

      receiver.receive(timeout);

Only debugging in Oracle JMS code brought us to this solution. There is poor documentation on this on the web.

Btw: the message selector led me in the complete wrong direction.

Thirdman
  • 621
  • 7
  • 13
  • What standard are you talking about with regards to dequeuing non-persistent messages? – Justin Bertram Feb 12 '20 at 20:56
  • I'm talking about JMS Standard, which defines a JMSDeliveryMode.NON_PERSISTENT (and I thought that it also should be possible to dequeue non persistent messages using JMS). – Thirdman Feb 13 '20 at 07:47
  • 2
    According to the JMS specification it's certainly possible to dequeue/consume non-persistent messages. If OracleAQ doesn't support this functionality then it isn't fully compliant with the JMS spec. – Justin Bertram Feb 13 '20 at 13:00
1

The JMS specification (JSR 914) defines two delivery modes: PERSISTENT and NON_PERSISTENT. Regarding Oracle these modes are PERSISTENT and BUFFERED.

However, it seems Oracles JMS implementation does only receives the PERSISTENT ones per default.

The message selector itself is checked by Oracle implementation, but seems not to have a effect on the delivery mode.

As stated by yourself, the QueueReceiver can be casted to a AQjmsConsumer to handle buffered messages.

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

The same applies when sending buffered messages. Here the QueueSender must be casted to a AQjmsProducer to have a method for buffered messages at hand:

AQjmsProducer producer = (AQjmsProducer)session.createProducer(queue);
producer.bufferSend(queue, msg, priority, timeToLive);
tafli
  • 152
  • 1
  • 8