Исключить очередь исключений в ORACLE AQ - PullRequest
1 голос
/ 06 января 2020

Я новичок в процессе Oracle AQ и у меня есть несколько вопросов об очереди исключений. Вот мой сценарий:

Oracle База данных 19 c Enterprise Edition Release 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;    
/

Насколько я понимаю, он должен повторить запрос 6 раз с задержкой в ​​30 минут и затем отправить его в очередь исключений. Но в моем случае он отправлял сообщения в очередь исключений намного раньше. Я хочу, чтобы ваши данные знали, если что-то пропущено или я делаю это неправильно.

Постановка в очередь:

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

Когда я выполняю постановку в очередь и если приложения закрываются или по каким-либо другим причинам, сообщения отправляются в очередь исключений. И если я исключаю из очереди исключений, нужно ли упоминать (XYZ_PACKAGE.ABC_API (MESSAGE.HN_TXN_SEQ); ---- CALL 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); ---- CALL API ----) где-то между?

Лучше ли выполнять очередь исключений или иметь max_retries и с retry_delay ?

Если сообщения перемещаются в очередь исключений, и если я запускаю запрос для их удаления из очереди. Следуют ли они тому же механизму, что и при снятии очереди с обычной очереди, и выполняют любые дополнительные API, которые используют сообщение в качестве входных данных?

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...