Thirdman
Thirdman

Reputation: 709

Dequeue Non_Persistent message from AQ Queue using JMS

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!

Upvotes: 1

Views: 557

Answers (2)

tafli
tafli

Reputation: 162

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);

Upvotes: 1

Thirdman
Thirdman

Reputation: 709

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.

Upvotes: 1

Related Questions