Я новичок в процессе 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, которые используют сообщение в качестве входных данных?
Спасибо!