Env: Oracle 12c
I currently have an Oracle Advanced Queue system setup as follows:
NAME QUEUE_TABLE QID QUEUE_TYPE MAX_RETRIES RETRY_DELAY RETENTION
--------------- --------------- ------- --------------- ----------- ----------- ---------
MY_WORK_Q MY_WORK_QT 2518333 NORMAL_QUEUE 100 0 0
MY_WORK_QT_E MY_WORK_QT 2518332 EXCEPTION_QUEUE 0 0 0
I also have registered a callback that calls a PL/SQL package procedure.
For some reason, I seem to have a situation where I am losing messages or messages are not being dequeued.
Based on this, I have the following questions:
- Have I setup my actual queue - MY_WORK_Q with MAX_RETRIES and other info correctly?
- Is there a way to check messages that have been enqueued?
- Is there a way to check messages that have been de-queued?
- Is there a means of checking the EXCEPTION_QUEUE/Exception table to see if lost messages have reached there?
I just can't see why I am losing messages within my queueing system and what I could check to see what might be causing the issue.
I also increased my MAX_RETRIES to 100 but still seem to be having issues.
Update
It seems like I am getting the error ORA-25263: no message in queue.
I am not sure if this is related to a timing issue on the dbms_aq.enqueue or dbms_aq.dequeue calls but on the dbms_aq.dequeue I have this set:
l_dequeue_options.wait := dbms_aq.no_wait;
Do I require say a 10 second wait instead of no_wait? I am unsure if this possible and whether the wait needs to be on the enqueue or dequeue steps.
Here is a simple example that works. Perhaps you can use it to identify your issue?
One thing that will definitely help you is setting retention_time on your queue table. You can then use the aq$ reference for the queue table to look at the messages. The msg_state column will show READY for a fresh message and PROCESSED for a message that was consumed. There are some other columns on there that can be helpful: retry_count for example.
If you are getting ORA-25263 it seems instead of handling the one message you are getting provoked for in your callback that you are trying to read a different message and clashing with another job that was started to consume the queue. This is resolved by the two lines I have in my callback before calling dequeue.
If you need to trigger when a message arrives and then preserve message order you need to add some locking and additional complexity to your callback. You could take a look at Metalink 225810.1 for examples on how to do this.