Search code examples
databaseoraclemessage-queueadvanced-queuing

Oracle AQ message lost after session killed while dequeue in progress


I have an issue with DBMS_AQ.deQueue on an Oracle 11g R2 Windows 2008 R2 database. When a session does a dequeue and it is killed after that (before a commit or rollback), the particular message is permanently removed from the queue. I would expect it to still be in the queue, or at least be in the exception queue. I perform the following steps to test:

  1. Enqueue from session 1, and commit. (see code below)
  2. Dequeue from session 2. (see code below)
  3. Session 1: select * from MY_Q_T -> my message is still visible here.
  4. Session 2: select * from MY_Q_T -> my message is not visible anymore.
  5. Kill Session 2 (the dequeue) session.
  6. Session 1: select * from MY_Q_T -> my message is not visible anymore. The message is lost.

Is this a bug? Since the dequeue (/visibility) is not set to be autonomous I would expect the message to be still in the queue when session 2 was killed. Any ideas for a workaround?

Code used for enqueue and dequeue:

ENQUEUE:

declare
    queue_options      DBMS_AQ.ENQUEUE_OPTIONS_T;
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
    message_id         raw(16);
    pl                 MY_PAYLPOAD_T;
begin
    DBMS_AQ.enQueue(queue_name         => 'MY_Q',
                    enqueue_options    => queue_options,
                    message_properties => message_properties,
                    payload            => pl,
                    msgid              => message_id);
end;

DEQUEUE:

declare
    queue_options      DBMS_AQ.DEQUEUE_OPTIONS_T;
    message_properties DBMS_AQ.MESSAGE_PROPERTIES_T;
    message_id         raw(2000);
    pl               MY_PAYLPOAD_T;
begin
    DBMS_AQ.DEQUEUE(queue_name         => 'MY_Q',
                  dequeue_options    => queue_options,
                  message_properties => message_properties,
                  payload            => pl,
                  msgid              => message_id);
end;

Solution

  • How are you killing the session ? It looks like you are just logging off from the session which defaults to committing any open transactions in the session in your client program. And since the dequeue transaction is committed, the message is gone from the queue.

    You can verify this by inserting a row into a table, kill/close your session and check if the row is added.