Plsql 将ORACLE AQ中的异常队列出列

Plsql 将ORACLE AQ中的异常队列出列,plsql,oracle-aq,advanced-queuing,enqueue,Plsql,Oracle Aq,Advanced Queuing,Enqueue,我是Oracle AQ流程的新手,对异常队列有一些问题。以下是我的设想: Oracle数据库19c企业版19.0.0.0.0版 创建表和队列: BEGIN DBMS_AQADM.CREATE_QUEUE_TABLE ( QUEUE_TABLE =>'ADD_QUEUE_TABLE', MULTIPLE_CONSUMERS => TRUE, QUEUE_PAYLOAD_TYPE => 'ADD_OBJECT_TYPE');

我是Oracle AQ流程的新手,对异常队列有一些问题。以下是我的设想:

Oracle数据库19c企业版19.0.0.0.0版

创建表和队列:

BEGIN

  DBMS_AQADM.CREATE_QUEUE_TABLE (
      QUEUE_TABLE  =>'ADD_QUEUE_TABLE',
      MULTIPLE_CONSUMERS   => TRUE,
      QUEUE_PAYLOAD_TYPE   => 'ADD_OBJECT_TYPE');

  DBMS_AQADM.CREATE_QUEUE (
      QUEUE_NAME  => 'ADD_QUEUE',
      QUEUE_TABLE => 'ADD_QUEUE_TABLE',
      max_retries => 6,
      retry_delay => 1800);

  DBMS_AQADM.START_QUEUE (QUEUE_NAME => 'ADD_QUEUE');

END;    
/
据我所知,它应该以30分钟的延迟重试6次出列,然后发送到异常队列。但在我的例子中,它以前确实多次将消息发送到异常队列。我想让你们知道我是否遗漏了什么或做错了什么

排队:

CREATE PROCEDURE TXN_ENQUEUE_PROCEDURE (HN_TXN_SEQ IN NUMBER)
AS
  ENQUEUE_OPTIONS      DBMS_AQ.ENQUEUE_OPTIONS_T;
  MESSAGE_PROPERTIES   DBMS_AQ.MESSAGE_PROPERTIES_T;
  MESSAGE_HANDLE       RAW (16);
  MESSAGE             TXN_OBJECT_TYPE;
BEGIN
  MESSAGE := TXN_OBJECT_TYPE (HN_TXN_SEQ);
  DBMS_AQ.ENQUEUE (QUEUE_NAME           => 'FILE_QUEUE',
                   ENQUEUE_OPTIONS      => ENQUEUE_OPTIONS,
                   MESSAGE_PROPERTIES   => MESSAGE_PROPERTIES,
                   PAYLOAD              => MESSAGE,
                   MSGID                => MESSAGE_HANDLE);
  COMMIT;
END;
/
出列:

CREATE OR REPLACE PROCEDURE TXN_DEQUEUE_PROCEDURE (
  CONTEXT    RAW,
  REGINFO    SYS.AQ$_REG_INFO,
  DESCR      SYS.AQ$_DESCRIPTOR,
  PAYLOAD    RAW,
  PAYLOADL   NUMBER)
AS
  DEQUEUE_OPTIONS      DBMS_AQ.DEQUEUE_OPTIONS_T;
  MESSAGE_PROPERTIES   DBMS_AQ.MESSAGE_PROPERTIES_T;
  MESSAGE_HANDLE       RAW (16);
  MESSAGE              TXN_OBJECT_TYPE;
BEGIN
  DEQUEUE_OPTIONS.WAIT := DBMS_AQ.NO_WAIT;
  DEQUEUE_OPTIONS.CONSUMER_NAME := 'MYSUBSCRIBER';
  DEQUEUE_OPTIONS.NAVIGATION := DBMS_AQ.FIRST_MESSAGE;
  DEQUEUE_OPTIONS.MSGID := DESCR.MSG_ID;
  DEQUEUE_OPTIONS.CONSUMER_NAME := DESCR.CONSUMER_NAME;
  LOOP
    DBMS_AQ.DEQUEUE (QUEUE_NAME           => DESCR.QUEUE_NAME,
                     DEQUEUE_OPTIONS      => DEQUEUE_OPTIONS,
                     MESSAGE_PROPERTIES   => MESSAGE_PROPERTIES,
                     PAYLOAD              => MESSAGE,
                     MSGID                => MESSAGE_HANDLE);
    INSERT INTO MESSAGE_TABLE_SAMPLE  VALUES (MESSAGE.HN_TXN_SEQ);

    XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL API ----
    COMMIT;
  END LOOP;
END;    
/
当我执行enqueue时,如果应用程序停止运行或由于任何其他原因,消息将进入异常队列。如果我从异常队列中出列,我是否需要在出列过程中提及(XYZ_PACKAGE.ABC_API(MESSAGE.HN_TXN_SEQ);----调用API----),或者它将像正常的队列出列过程一样被自动调用

异常队列:

EXECUTE DBMS_AQADM.START_QUEUE('AQ$_FILE_QUEUE_TABLE_E', false, true);

DECLARE
  dequeue_options DBMS_AQ.dequeue_options_t;
  message_properties DBMS_AQ.message_properties_t;
  dq_msgid RAW(16);
  payload RAW(1);
  no_messages exception;
  pragma exception_init (no_messages, -25263);
  msg_count number(2);
  cursor c_msg_ids is
    select msg_id
    from aq$FILE_QUEUE_TABLE
    where queue = 'AQ$_FILE_QUEUE_TABLE_E';
BEGIN
  dequeue_options.consumer_name := null;
  dequeue_options.wait := DBMS_AQ.NO_WAIT;
  dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
  dequeue_options.dequeue_mode := dbms_aq.remove_nodata;
  For v_msg_id in c_msg_ids loop
    dequeue_options.msgid := v_msg_id.msg_id;
    msg_count := 0;
    DBMS_AQ.DEQUEUE(queue_name => 'sys.AQ$_FILE_QUEUE_TABLE_E',
                    dequeue_options => dequeue_options,
                    message_properties => message_properties,
                    payload => payload,
                    msgid => dq_msgid);
    dbms_output.put_line('Message id : '||v_msg_id.msg_id||' removed');
    msg_count := msg_count + 1;
    dequeue_options.msgid := null;
    dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;
  END LOOP;
EXCEPTION
  WHEN no_messages THEN
    DBMS_OUTPUT.PUT_LINE ('No of Messages Removed: '||msg_count);
    COMMIT;
END;
/
执行上述操作后,它将从异常队列中删除消息。我是否需要在这两者之间的任何地方提到(XYZ_PACKAGE.ABC_API(MESSAGE.HN_TXN_SEQ)----调用API----

是执行异常队列更好,还是具有最大重试次数和重试延迟更好

如果消息移动到异常队列,并且如果我运行一个查询将它们出列。它们是否遵循与普通队列出列相同的机制,并执行使用消息作为输入的任何其他API

谢谢大家!