4

問題の解決策が見つからないようです。これで何時間も立ち往生しています。

私はOracle AQを使用しています:

       Dbms_Aqadm.Create_Queue_Table(Queue_Table        => 'ITEM_EVENT_QT',
                                    Queue_Payload_Type => 'ITEM_EVENT',
                                    Multiple_Consumers => TRUE);

       Dbms_Aqadm.Create_Queue(Queue_Name          => 'ITEM_EVENT_QUEUE',
                              Queue_Table         => 'ITEM_EVENT_QT',
                              Max_Retries         => 5,
                              Retry_Delay         => 0,
                              Retention_Time      => 432000, -- 5 DAYS
                              Dependency_Tracking => FALSE,
                              COMMENT             => 'Item Event Queue');
       -- START THE QUEUE
       Dbms_Aqadm.Start_Queue('ITEM_EVENT_QUEUE');
       -- GRANT QUEUE PRIVILEGES
       Dbms_Aqadm.Grant_Queue_Privilege(Privilege    => 'ALL',
                                       Queue_Name   => 'ITEM_EVENT_QUEUE',
                                       Grantee      => 'PUBLIC',
                                       Grant_Option => FALSE);
    END;

これが私のサブスクライバーの 1 つです。

Dbms_Aqadm.Add_Subscriber(Queue_Name => 'ITEM_EVENT_QUEUE',
                            Subscriber => Sys.Aq$_Agent('ITEM_SUBSCRIBER_1',
                                                        NULL,
                                                        NULL),
                            rule   =>  'tab.user_data.header.thread_no = 1');

   Dbms_Aq.Register(Sys.Aq$_Reg_Info_List(Sys.Aq$_Reg_Info('ITEM_EVENT_QUEUE:ITEM_SUBSCRIBER_1',
                                                          Dbms_Aq.Namespace_Aq,
                                                          'plsql://ITEM_API.GET_QUEUE_FROM_QUEUE',
                                                          HEXTORAW('FF'))),1);

加入者登録:

DB で特定のイベントが発生するたびに、ITEM_APIパッケージから次のプロシージャを呼び出して、トリガーを使用して AQ に「イベント」を追加しています。

  PROCEDURE ADD_EVENT_TO_QUEUE(I_EVENT       IN ITEM_EVENT,
                               O_STATUS_CODE OUT VARCHAR2,
                               O_ERROR_MSG   OUT VARCHAR2) IS

    ENQUEUE_OPTIONS    DBMS_AQ.ENQUEUE_OPTIONS_T;
    MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
    MESSAGE_HANDLE     RAW(16);
    EVENT              ITEM_EVENT;
    HEADER_PROP        HEADER_PROPERTIES;
  BEGIN
    EVENT                              := I_EVENT;
    EVENT.SEQ_NO                       := ITEM_EVENT_SEQ.NEXTVAL;
    ENQUEUE_OPTIONS.VISIBILITY         := DBMS_AQ.ON_COMMIT;
    ENQUEUE_OPTIONS.SEQUENCE_DEVIATION := NULL;
    MESSAGE_PROPERTIES.PRIORITY        := 1;
    MESSAGE_PROPERTIES.DELAY           := DBMS_AQ.NO_DELAY;
    MESSAGE_PROPERTIES.EXPIRATION      := DBMS_AQ.NEVER;
    HEADER_PROP                        := HEADER_PROPERTIES(1);
    EVENT.HEADER                       := HEADER_PROP;
    DBMS_AQ.ENQUEUE(QUEUE_NAME         => 'ITEM_EVENT_QUEUE',
                    ENQUEUE_OPTIONS    => ENQUEUE_OPTIONS,
                    MESSAGE_PROPERTIES => MESSAGE_PROPERTIES,
                    PAYLOAD            => EVENT,
                    MSGID              => MESSAGE_HANDLE);
  EXCEPTION
    WHEN OTHERS THEN
      ERROR_HANDLER.LOG_ERROR(NULL,
                              EVENT.ITEM,
                              EVENT.SEQ_NO,
                              SQLCODE,
                              SQLERRM,
                              O_STATUS_CODE,
                              O_ERROR_MSG);
      RAISE;
  END ADD_EVENT_TO_QUEUE;

AQテーブルをチェックすると「イベント」が見つかるため、機能していますが、次の画像でわかるように、デキューメソッドはデキューされていませんDEQ_TIME

ITEM_APIこれも私のパッケージからの私のデキュー方法です:

  PROCEDURE GET_QUEUE_FROM_QUEUE(CONTEXT  RAW,
                                 REGINFO  SYS.AQ$_REG_INFO,
                                 DESCR    SYS.AQ$_DESCRIPTOR,
                                 PAYLOAD  RAW,
                                 PAYLOADL NUMBER) IS

    R_DEQUEUE_OPTIONS    DBMS_AQ.DEQUEUE_OPTIONS_T;
    R_MESSAGE_PROPERTIES DBMS_AQ.MESSAGE_PROPERTIES_T;
    V_MESSAGE_HANDLE     RAW(16);
    I_PAYLOAD            ITEM_EVENT;
    L_PROC_EVENT         BOOLEAN;
    O_TARGETS            CFG_EVENT_STAGE_TBL;
    O_ERROR_MSG          VARCHAR2(300);
    O_STATUS_CODE        VARCHAR2(100);
  BEGIN
    R_DEQUEUE_OPTIONS.MSGID         := DESCR.MSG_ID;
    R_DEQUEUE_OPTIONS.CONSUMER_NAME := DESCR.CONSUMER_NAME;
    R_DEQUEUE_OPTIONS.DEQUEUE_MODE  := DBMS_AQ.REMOVE;
    --R_DEQUEUE_OPTIONS.WAIT          := DBMS_AQ.NO_WAIT;
    DBMS_AQ.DEQUEUE(QUEUE_NAME         => DESCR.QUEUE_NAME,
                    DEQUEUE_OPTIONS    => R_DEQUEUE_OPTIONS,
                    MESSAGE_PROPERTIES => R_MESSAGE_PROPERTIES,
                    PAYLOAD            => I_PAYLOAD,
                    MSGID              => V_MESSAGE_HANDLE);
    IF I_PAYLOAD IS NOT NULL THEN
      L_PROC_EVENT := PROCESS_EVENT(I_PAYLOAD,
                                    O_TARGETS,
                                    O_STATUS_CODE,
                                    O_ERROR_MSG);
    END IF;
  EXCEPTION
    WHEN OTHERS THEN
      ERROR_HANDLER.LOG_ERROR(NULL,
                              NULL,
                              NULL,
                              SQLCODE,
                              SQLERRM,
                              O_STATUS_CODE,
                              O_ERROR_MSG);
      RAISE;
  END GET_QUEUE_FROM_QUEUE;

私は何か間違ったことをしていますか?どうすればこれを修正できますか? 購読者登録に問題があるのではないかと思いますが、よくわかりません。

編集:サブスクライバーとレジスターを削除してから再度追加すると、すべてのメッセージがデキューされることがわかりました。ただし、別のイベントがキューに入れられた場合、それは無期限にそこにとどまります (または、サブスクライバーを削除して再度追加するまで):

状態が 0 で no のレコードがDEQ_TIME新しいレコードです。

スケジューラなどが必要ですか?

編集: AQにスケジューラの伝播を追加しました:

DBMS_AQADM.SCHEDULE_PROPAGATION('ITEM_EVENT_QUEUE');

さらに next_time フィールドを追加しました。

DBMS_AQADM.SCHEDULE_PROPAGATION('ITEM_EVENT_QUEUE', SYSDATE + 30/86400);

それでもうまくいきません。助言がありますか?AQ 通知が機能していないようで、コールバック プロシージャが呼び出されません。どうすればこれを修正できますか?

編集:テスト目的のためだけにパッケージから手順を削除したので、チーム メイトは ITEM_API パッケージをコンパイルできます (パッケージを再コンパイルするかどうかはわかりませんが、デキュー プロセスに影響がある場合とない場合があります)。それでもうまくいきません。

4

3 に答える 3

0

同じ問題に直面しましたが、次の 2 つの DB パラメータを変更すると解決しました。

  1. job_queue_processes (> 0 である必要があります)
  2. aq_tm_processes (自動チューニング)

それが役に立てば幸い。

于 2015-06-24T15:36:52.120 に答える