ヘッダーをスキップ
Oracle® Streamsアドバンスト・キューイング・ユーザーズ・ガイド
11gリリース2 (11.2)
B61355-04
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

10 PL/SQLを使用したOracle Streams Advanced Queuing操作

この章では、Oracle Streams Advanced Queuing(AQ)のPL/SQL操作インタフェースについて説明します。

内容は次のとおりです。


関連項目:

  • 各プログラム・インタフェースで使用可能な機能のリストは、第3章「Oracle Streams Advanced Queuing: プログラム・インタフェース」を参照してください。

  • PL/SQLインタフェースの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』のDBMS_AQに関する項を参照してください。

  • Visual Basic(OO4O)インタフェースの詳細は、「Oracle Objects for OLE Online Help」のContentsタブから、OO4O Automation Server→OBJECTS→OraAQ Objectを選択してください。

  • Javaインタフェースの詳細は、『Oracle Streams Advanced Queuing Java API Reference』を参照してください。

  • Oracle Call Interface(OCI)の詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』のOCIリレーショナル関数に関する項およびOCIプログラミングの高度なトピックに関する項を参照してください。


保護キューの使用方法

保護キューの場合は、messages_propertiesパラメータにsender_idを指定する必要があります。sender_idの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』のMESSAGE_PROPERTIES_T型に関する項を参照してください。

保護キューを使用する場合の要件は、次のとおりです。

メッセージのエンキュー

DBMS_AQ.ENQUEUE(
   queue_name          IN      VARCHAR2,
   enqueue_options     IN      enqueue_options_t,
   message_properties  IN      message_properties_t,
   payload             IN      "type_name",
   msgid               OUT     RAW);

このプロシージャにより、指定のキューメッセージが追加されます。

メッセージのエンキュー後は、メッセージ・ペイロードを更新できません。メッセージ・ペイロードを変更する場合は、メッセージをデキューして新規メッセージをエンキューする必要があります。

RAW型のペイロードを格納するために、Oracle Streams Advanced Queuingでは、ペイロード・リポジトリとしてLOB列を持つキュー表が作成されます。ペイロードの最大サイズは、Oracle Streams Advanced Queuingへのアクセスに使用するプログラム・インタフェースによって決まります。PL/SQL、Javaおよびプリコンパイラの場合は32KB、OCIの場合は4GBに制限されます。

メッセージが受信者を指定しないでマルチ・コンシューマ・キューにエンキューされ、そのキューにサブスクライバが指定されていない(またはそのメッセージに一致するルールベースのサブスクライバが存在しない)場合、ORA-24033エラーになります。これは、配信先の受信者またはサブスクライバが存在しないメッセージは廃棄されるという警告です。

複数のメッセージが同時にエンキューされると、すべてのenq_timeが同一になります。この場合、メッセージのデキュー順序は、同じenq_timeを持つ各メッセージに対して定量的に増加する変数step_noによって決まります。同じセッション中にエンキューされる2つのメッセージについて、enq_timestep_noの両方が同一になることはありません。

エンキュー・オプション

enqueue_optionsパラメータでは、エンキュー操作に使用可能なオプションを指定します。属性は次のとおりです。

  • visibility

    visibility属性では、エンキュー・リクエストのトランザクション動作を指定します。ON_COMMIT(デフォルト)を指定すると、エンキューは現行のトランザクションの一部になります。IMMEDIATEを指定すると、エンキュー操作は操作の最後にコミットする自律型トランザクションになります。

    LOBロケータを使用するときは、IMMEDIATEオプションを使用しないでください。LOBロケータは、トランザクションが継続している間のみ有効です。IMMEDIATEオプションを使用すると、トランザクションが自動的にコミットされるため、ロケータは有効になりません。

    バッファ済メッセージを使用するには、visibility属性をIMMEDIATEに設定する必要があります。

  • relative_msgid

    relative_msgid属性では、順序逸脱操作で参照されるメッセージのメッセージIDを指定します。このパラメータは、sequence_deviationBEFORE属性を指定しないと無視されます。

  • sequence_deviation

    sequence_deviation属性では、すでにキューにある他のメッセージを基準にしてメッセージのデキュー時期を指定します。BEFOREを指定すると、メッセージはrelative_msgidで指定したメッセージの前に配置されます。TOPを指定すると、メッセージは他のすべてのメッセージの前に配置されます。

    メッセージにsequence_deviationを指定すると、そのメッセージに指定できる遅延および優先順位の値が制限されます。このメッセージの遅延の値は、このメッセージより前にエンキューされるメッセージの遅延の値以下にする必要があります。このメッセージの優先順位の値は、このメッセージより前にエンキューされるメッセージの優先順位以上にする必要があります。


    注意:

    Oracle Streams Advanced Queuing 10gリリース1(10.1)より前のリリースでは、message_groupingTRANSACTIONALに設定されている場合、sequence_deviation属性は無効です。

    順序逸脱機能は、Oracle Streams Advanced Queuing 10gリリース2(10.2)では非推奨になりました。


  • transformation

    transformation属性では、メッセージのエンキュー前に適用する変換を指定します。変換ファンクションの戻り型は、キューの型と一致する必要があります。

  • delivery_mode

    delivery_mode属性のデフォルトはPERSISTENTで、メ_ッセージは永続メッセージとしてエンキューされます。BUFFEREDに設定すると、メッセージはバッファ済メッセージとしてエンキューされます。NULL値は設定できません。

メッセージ・プロパティ

message_propertiesパラメータには、Oracle Streams Advanced Queuingでメッセージを個別に管理するために使用される情報が含まれます。属性は次のとおりです。

  • priority

    priority属性では、メッセージの優先順位を指定します。これには、負数も含めたあらゆる数値を使用できます。数値が小さいほど高い優先度を示します。

  • delay

    delay属性では、メッセージがWAITING状態になっている秒数を指定します。この秒数をすぎると、メッセージはREADY状態になり、デキュー可能になります。NO_DELAYを指定すると、メッセージは即時にデキュー可能になります。msgidを指定してデキューすると、delay指定がオーバーライドされます。


    注意:

    バッファ済メッセージではdelayはサポートされません。

  • expiration

    expiration属性では、メッセージがREADY状態になった後でデキュー可能な秒数を指定します。期限切れになる前にデキューされない場合、メッセージはEXPIRED状態で例外キューに移されます。NEVERを指定すると、メッセージは期限切れになりません。


    注意:

    メッセージの遅延および期限切れの処理は、キュー・モニター(QMN)のバックグラウンド・プロセスによって行われます。Oracle Streams Advanced Queuingの遅延および期限切れの機能を使用するときは、データベースのQMNプロセスを開始する必要があります。

  • correlation

    correlation属性は、エンキュー時にメッセージのプロデューサが指定する識別子です。

  • attempts

    attempts属性は、メッセージをデキューするために実行された試行回数を指定します。このパラメータは、エンキュー時には設定できません。

  • recipient_list

    recipient_listパラメータは、マルチ・コンシューマに対応するキューにのみ有効です。デフォルトの受信者はキューのサブスクライバです。

  • exception_queue

    exception_queue属性では、正常に処理できない場合にメッセージが移されるキューの名前を指定します。メッセージの移動時に指定された例外キューが存在しない場合、メッセージはキュー表に対応付けられたデフォルトの例外キューに移され、アラート・ログに警告が記録されます。

  • delivery_mode

    エンキュー時にメッセージ・プロパティで指定したdelivery_modeの値は無視されます。エンキュー・オプションで指定した値を使用して、メッセージの配信モードが設定されます。エンキュー・オプションで配信モードを指定しなければ、デフォルトでPERSISTENTに設定されます。

  • enqueue_time

    enqueue_time属性では、メッセージがエンキューされた時刻を指定します。この値はシステムにより決定され、ユーザーはエンキュー時に設定できません。


    注意:

    システム・クロックの季節変動情報(標準時と夏時間の間の切替えなど)は各キュー表とともに格納されるため、季節変動は自動的にenqueue_timeに反映されます。他のなんらかの理由でシステム・クロックに変更があった場合は、Oracle Streams Advanced Queuing用のデータベースを再起動して変更後の時刻を取得する必要があります。

  • state

    state属性では、デキュー時のメッセージの状態を指定します。このパラメータは、エンキュー時には設定できません。

  • sender_id

    sender_id属性は、メッセージ・プロデューサがエンキュー時に指定したaq$_agent型の識別子です。

  • original_msgid

    original_msgid属性は、Oracle Streams AQでメッセージの伝播に使用されます。

  • transaction_group

    transaction_group属性では、メッセージのトランザクション・グループを指定します。この属性は、DBMS_AQ.DEQUEUE_ARRAYでのみ設定されます。DBMS_AQ.ENQUEUEまたはDBMS_AQ.ENQUEUE_ARRAYを介してメッセージのトランザクション・グループを設定する場合、この属性は使用できません。

  • user_property

    user_property属性はオプションです。ペイロードの追加情報の格納に使用します。

この章の例には、第8章「Oracle Streams Advanced Queuing管理インタフェース」の例と同じユーザー、メッセージ型、キュー表およびキューを使用しています。まだこれらの構造をテスト環境で作成していない場合は、次の例を実行する必要があります。

例8-1では、管理権限を持つユーザーとして接続する必要があります。前述のリストの他の例では、ユーザーtest_admとして接続できます。キューの作成後に、「キューの開始」に示すようにキューを開始する必要があります。特に明記しないかぎり、この章に示すすべての例は通常のキュー・ユーザー'test'として接続して実行できます。

例10-1 キュー名とペイロードを指定したメッセージのエンキュー

DECLARE
   enqueue_options     DBMS_AQ.enqueue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   message := test.message_typ(001, 'TEST MESSAGE', 'First message to obj_queue');
   DBMS_AQ.ENQUEUE(
      queue_name              => 'test.obj_queue',
      enqueue_options         => enqueue_options,
      message_properties      => message_properties,
      payload                 => message,
      msgid                   => message_handle);
   COMMIT;
END;
/

例10-2 優先順位を指定したメッセージのエンキュー

DECLARE 
   enqueue_options       DBMS_AQ.enqueue_options_t; 
   message_properties    DBMS_AQ.message_properties_t; 
   message_handle        RAW(16); 
   message               test.order_typ; 
BEGIN 
   message := test.order_typ(002, 'PRIORITY MESSAGE', 'priority 30'); 
   message_properties.priority := 30; 
   DBMS_AQ.ENQUEUE(
      queue_name              => 'test.priority_queue', 
      enqueue_options         => enqueue_options, 
      message_properties      => message_properties, 
      payload                 => message, 
      msgid                   => message_handle); 
   COMMIT; 
END;
/

LOB型メッセージのエンキュー

例10-3では、例8-1で作成したtest.lob_typeメッセージ・ペイロード・オブジェクト型を使用して、プロシージャblobenqueue()を作成します。エンキュー時に、LOB属性がEMPTY_BLOBに設定されます。エンキューの完了後、トランザクションがコミットされる前に、test.lob_qtabキュー表のuser_data列からLOB属性が選択されます。LOBデータは、LOBインタフェース(OCIおよびPL/SQLの両方を介して使用可能)を使用してキューに書き込まれます。実際のエンキュー操作は、を参照してください。

デキュー時には、メッセージ・ペイロードにLOBロケータが含まれます。デキュー後、トランザクションがコミットされる前に、このLOBロケータを使用してLOBデータを読み取ることができます。例10-14を参照してください。

例10-3 LOB型メッセージのエンキュー・プロシージャの作成

CREATE OR REPLACE PROCEDURE blobenqueue(msgno IN NUMBER) AS
   enq_userdata          test.lob_typ; 
   enq_msgid             RAW(16); 
   enqueue_options       DBMS_AQ.enqueue_options_t; 
   message_properties    DBMS_AQ.message_properties_t; 
   lob_loc               BLOB; 
   buffer                RAW(4096); 
BEGIN 
   buffer       := HEXTORAW(RPAD('FF', 4096, 'FF')); 
   enq_userdata := test.lob_typ(msgno, 'Large Lob data', EMPTY_BLOB(), msgno); 
   DBMS_AQ.ENQUEUE(
      queue_name          => 'test.lob_queue',
      enqueue_options     => enqueue_options,
      message_properties  => message_properties,
      payload             => enq_userdata, 
      msgid               => enq_msgid); 
   SELECT t.user_data.data INTO lob_loc 
      FROM lob_qtab t 
      WHERE t.msgid = enq_msgid; 
   DBMS_LOB.WRITE(lob_loc, 2000, 1, buffer ); 
   COMMIT; 
END;
/ 

例10-4 LOB型メッセージのエンキュー

BEGIN 
   FOR i IN 1..5 LOOP 
      blobenqueue(i); 
   END LOOP; 
END;
/

シングル・コンシューマ・キューへの複数メッセージのエンキュー

例10-5では、6つのメッセージをtest.obj_queueにエンキューしています。これらのメッセージは、例10-17でデキューされます。

例10-5 複数メッセージのエンキュー

SET SERVEROUTPUT ON
DECLARE
   enqueue_options     DBMS_AQ.enqueue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   message := test.message_typ(001, 'ORANGE', 'ORANGE enqueued first.');
   DBMS_AQ.ENQUEUE(
         queue_name           => 'test.obj_queue', 
         enqueue_options      => enqueue_options,
         message_properties   => message_properties,
         payload              => message,
         msgid                => message_handle);
   message := test.message_typ(001, 'ORANGE', 'ORANGE also enqueued second.');
   DBMS_AQ.ENQUEUE(
         queue_name           => 'test.obj_queue', 
         enqueue_options      => enqueue_options,
         message_properties   => message_properties,
         payload              => message,
         msgid                => message_handle);
   message := test.message_typ(001, 'YELLOW', 'YELLOW enqueued third.');
   DBMS_AQ.ENQUEUE(
         queue_name           => 'test.obj_queue', 
         enqueue_options      => enqueue_options,
         message_properties   => message_properties,
         payload              => message,
         msgid                => message_handle);
   message := test.message_typ(001, 'VIOLET', 'VIOLET enqueued fourth.');
   DBMS_AQ.ENQUEUE(
         queue_name           => 'test.obj_queue', 
         enqueue_options      => enqueue_options,
         message_properties   => message_properties,
         payload              => message,
         msgid                => message_handle);
   message := test.message_typ(001, 'PURPLE', 'PURPLE enqueued fifth.');
   DBMS_AQ.ENQUEUE(
         queue_name           => 'test.obj_queue', 
         enqueue_options      => enqueue_options,
         message_properties   => message_properties,
         payload              => message,
         msgid                => message_handle);
   message := test.message_typ(001, 'PINK', 'PINK enqueued sixth.');
   DBMS_AQ.ENQUEUE(
         queue_name           => 'test.obj_queue', 
         enqueue_options      => enqueue_options,
         message_properties   => message_properties,
         payload              => message,
         msgid                => message_handle);
   COMMIT;
END;
/

マルチ・コンシューマ・キューへの複数メッセージのエンキュー

例10-6では、ユーザー'test_adm'として接続し、キューtest.multiconsumer_queueにサブスクライバREDおよびGREENを追加する必要があります。この2つのサブスクライバは例10-7で必要になります。

例10-6 サブスクライバREDおよびGREENの追加

DECLARE
   subscriber         sys.aq$_agent;
BEGIN
   subscriber     :=  sys.aq$_agent('RED', NULL, NULL);
   DBMS_AQADM.ADD_SUBSCRIBER(
      queue_name  =>  'test.multiconsumer_queue',
      subscriber  =>  subscriber);

   subscriber     :=  sys.aq$_agent('GREEN', NULL, NULL);
   DBMS_AQADM.ADD_SUBSCRIBER(
      queue_name  =>  'test.multiconsumer_queue',
      subscriber  =>  subscriber); 
END;
/

例10-7では、送信者001からの複数のメッセージをエンキューします。MESSAGE 1はすべてのキュー・サブスクライバを対象としています。MESSAGE 2はREDおよびBLUEを対象としています。これらのメッセージは、例10-17でデキューされます。

例10-7 マルチ・コンシューマ・キューへの複数メッセージのエンキュー

DECLARE
   enqueue_options     DBMS_AQ.enqueue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   recipients          DBMS_AQ.aq$_recipient_list_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   message := test.message_typ(001, 'MESSAGE 1','For queue subscribers');
   DBMS_AQ.ENQUEUE(
      queue_name          => 'test.multiconsumer_queue',
      enqueue_options     => enqueue_options,
      message_properties  => message_properties,
      payload             => message,
      msgid               => message_handle);

   message := test.message_typ(001, 'MESSAGE 2', 'For two recipients');
   recipients(1) := sys.aq$_agent('RED', NULL, NULL);
   recipients(2) := sys.aq$_agent('BLUE', NULL, NULL);
   message_properties.recipient_list := recipients;
   DBMS_AQ.ENQUEUE(
      queue_name          => 'test.multiconsumer_queue',
      enqueue_options     => enqueue_options,
      message_properties  => message_properties,
      payload             => message,
      msgid               => message_handle);
   COMMIT;
END;
/

グループ化されたメッセージのエンキュー

例10-8では、3つのメッセージ・グループをエンキューし、各グループにはメッセージが3つずつ含まれます。これらのメッセージは、例10-16でデキューされます。

例10-8 グループ化されたメッセージのエンキュー

DECLARE
   enqueue_options     DBMS_AQ.enqueue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
  FOR groupno in 1..3 LOOP
    FOR msgno in 1..3 LOOP
      message := test.message_typ(
               001,
               'GROUP ' || groupno, 
               'Message ' || msgno || ' in group ' || groupno);
      DBMS_AQ.ENQUEUE(
         queue_name             => 'test.group_queue',
         enqueue_options        => enqueue_options,
         message_properties     => message_properties,
         payload                => message,
         msgid                  => message_handle);
    END LOOP;
    COMMIT; 
  END LOOP;
END;
/

遅延および期限切れのメッセージのエンキュー

例10-9のアプリケーションでは、メッセージは現時点の1週間前から3週間後までの期間内にデキューされる必要があります。期限切れは最も早いデキュー時刻から計算されるため、この場合は期限切れを2週間に設定する必要があります。

例10-9 遅延と期限切れを指定したメッセージのエンキュー

DECLARE
   enqueue_options     DBMS_AQ.enqueue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   message := test.message_typ(001, 'DELAYED', 'Message is delayed one week.');
   message_properties.delay      := 7*24*60*60;
   message_properties.expiration := 2*7*24*60*60;
   DBMS_AQ.ENQUEUE(
      queue_name           => 'test.obj_queue',
      enqueue_options      => enqueue_options,
      message_properties   => message_properties,
      payload              => message,
      msgid                => message_handle);
   COMMIT;
END;
/

例10-10 変換を指定したメッセージのエンキュー

DECLARE
   enqueue_options     DBMS_AQ.enqueue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   message := test.message_typ(001, 'NORMAL MESSAGE', 'enqueued to obj_queue');
   enqueue_options.transformation := 'message_order_transform';
   DBMS_AQ.ENQUEUE(
      queue_name              => 'test.priority_queue', 
      enqueue_options         => enqueue_options,
      message_properties      => message_properties,
      payload                 => message,
      msgid                   => message_handle);
   COMMIT;
END;
/

関連項目:

OO4Oのメッセージ・エンキューの例は、『Oracle Objects for OLE開発者ガイド』のアドバンスト・キューイング・インタフェースの使用に関する項を参照してください。

メッセージの配列のエンキュー

DBMS_AQ.ENQUEUE_ARRAY(
   queue_name                IN   VARCHAR2,
   enqueue_options           IN   enqueue_options_t,
   array_size                IN   PLS_INTEGER,
   message_properties_array  IN   message_properties_array_t,
   payload_array             IN   VARRAY,
   msid_array                OUT  msgid_array_t)
RETURN PLS_INTEGER;

ENQUEUE_ARRAY関数を使用して、対応する配列のメッセージ・プロパティを使用するペイロードの配列をエンキューします。結果には、エンキューされたメッセージのメッセージ識別子の配列が出力されます。関数はエンキューに成功したメッセージの数を戻します。

バッファ済メッセージの場合、配列のエンキューはサポートされていませんが、array_size1に設定してDBMS_AQ.ENQUEUE_ARRAY()を使用すると、バッファ済メッセージをエンキューできます。

message_properties_arrayパラメータは、メッセージ・プロパティの配列です。このレコードには、ペイロードの配列の各要素に対応する要素が必要です。配列内のすべてのメッセージの配信モードは同じです。

ペイロード構造は、VARRAYまたはネストした表のいずれかです。メッセージIDは、DBMS_AQ.msgid_array_t型のRAW(16)のエントリの配列に戻されます。

リレーショナルDB環境における配列操作と同様に、すべての状況に対応可能な1つの最適な配列サイズを指定することはできません。アプリケーション開発者は、様々な配列サイズをテストして、各アプリケーションにとって最適な値を決定する必要があります。

例10-11 メッセージの配列のエンキュー

DECLARE
  enqueue_options       DBMS_AQ.enqueue_options_t;
  msg_prop_array        DBMS_AQ.message_properties_array_t;
  msg_prop              DBMS_AQ.message_properties_t;
  payload_array         test.msg_table;
  msgid_array           DBMS_AQ.msgid_array_t;
  retval                PLS_INTEGER;
BEGIN
  payload_array  := msg_table(
      message_typ(001, 'MESSAGE  1', 'array enqueued to obj_queue'), 
      message_typ(001, 'MESSAGE  2', 'array enqueued to obj_queue'));
  msg_prop_array := DBMS_AQ.message_properties_array_t(msg_prop, msg_prop);
 
  retval := DBMS_AQ.ENQUEUE_ARRAY( 
                 queue_name               => 'test.obj_queue',
                 enqueue_options          => enqueue_options,
                 array_size               => 2,
                 message_properties_array => msg_prop_array,
                 payload_array            => payload_array,
                 msgid_array              => msgid_array);
  COMMIT;
END;/

1つ以上のキューのリスニング

DBMS_AQ.LISTEN(
   agent_list             IN    aq$_agent_list_t,
   wait                   IN    BINARY_INTEGER DEFAULT FOREVER, 
   listen_delivery_mode   IN    PLS_INTEGER DEFAULT PERSISTENT,
   agent                  OUT   sys.aq$_agent
   message_delivery_mode  OUT   PLS_INTEGER);

TYPE aq$_agent_list_t IS TABLE of aq$_agent INDEXED BY BINARY_INTEGER;

このプロシージャでは、監視するキューを指定します(複数可)。

このコールの引数に、エージェント・リストがあります。各エージェントは、名前、アドレスおよびプロトコルの一意の組合せで識別されます。

各エージェント・リストのアドレス・フィールドには、監視するキューを指定します。エージェントには、監視対象の各キューに対するデキュー権限が必要です。マルチ・コンシューマ・キューを監視する場合はエージェント名を指定する必要がありますが、シングル・コンシューマ・キューの場合、エージェント名を指定する必要はありません。アドレスでサポートされているのは、ローカル・キューのみです。プロトコルは、将来の使用に備えて確保されています。


注意:

マルチ・コンシューマ・キューのリスニングはJava APIではサポートされていません。

listen_delivery_modeパラメータでは、エージェントの対象メッセージの型を指定します。デフォルトのPERSISTENTの場合、エージェントには永続メッセージのみが通知されます。BUFFEREDに設定すると、エージェントにはバッファ済メッセージのみが通知されます。PERSISTENT_OR_BUFFEREDに設定すると、エージェントには両方の型が通知されます。

このコールは、リストにあるエージェントによって処理可能なメッセージがある場合にエージェントとメッセージ型を戻すブロッキング・コールです。処理可能なエージェントが複数ある場合、最初にリストされたエージェントのみが戻されます。待機期限切れになった時点で1つもメッセージがない場合は、エラーになります。

Listenコールから正常に戻っても、指定されたキューの1つにリストされたいずれかのエージェントのメッセージがあることを意味しているにすぎません。処理するエージェントは、その関連メッセージをデキューする必要があります。


注意:

非永続キューにはLISTENはコールできません。

例10-12 シングル・コンシューマ・キューのリスニング(タイムアウト0(ゼロ))

SET SERVEROUTPUT ON
DECLARE
   agent            sys.aq$_agent;
   test_agent_list  DBMS_AQ.aq$_agent_list_t;
BEGIN
   test_agent_list(1) := sys.aq$_agent(NULL, 'test.obj_queue',  NULL);
   test_agent_list(2) := sys.aq$_agent(NULL, 'test.priority_queue', NULL);
   DBMS_AQ.LISTEN(
      agent_list   =>   test_agent_list, 
      wait         =>   0, 
      agent        =>   agent);
   DBMS_OUTPUT.PUT_LINE('Message in Queue: ' ||  agent.address);
END;
/

test.obj_queuetest.priority_queueの両方にメッセージ(それぞれ例10-1および例10-2でエンキュー)が含まれていますが、例10-12では次の値のみが戻されます。

Message in Queue: "TEST"."OBJ_QUEUE"

test_agent_listでエージェントの順序が保持される場合、test.priority_queuetest.obj_queueの前に表示されるため、この例では次のように戻されます。

Message in Queue: "TEST"."PRIORITY_QUEUE"

メッセージのデキュー

DBMS_AQ.DEQUEUE(
   queue_name          IN      VARCHAR2,
   dequeue_options     IN      dequeue_options_t,
   message_properties  OUT     message_properties_t,
   payload             OUT     "type_name",
   msgid               OUT     RAW);

このプロシージャでは、メッセージを指定のキューからデキューします。Oracle Streams Advanced Queuing 10gリリース2(10.2)からは、デキュー対象として永続メッセージのみ、バッファ済メッセージのみ、またはその両方を選択できます。次に示すデキュー・オプションのリストのdelivery_modeを参照してください。

デキュー・オプション

dequeue_optionsパラメータでは、デキュー操作に使用可能なオプションを指定します。属性は次のとおりです。

  • consumer_name

    コンシューマは、DBMS_AQADM.ADD_SUBSCRIBERプロシージャのAQ$_AGENT型またはメッセージ・プロパティの受信者リストに使用した名前を指定して、キューからメッセージをデキューできます。値を指定すると、consumer_nameと一致するメッセージのみがアクセスされます。キューがマルチ・コンシューマ用に設定されていない場合は、このフィールドをNULL(デフォルト)に設定する必要があります。

  • dequeue_mode

    dequeue_mode属性では、デキュー関連のロック動作を指定します。BROWSEを指定すると、メッセージはロックを取得せずにデキューされます。LOCKEDを指定すると、メッセージはデキューされ、トランザクションの期間中は書込みロックが継続します。REMOVEを指定すると、メッセージはデキューされて削除されます(デフォルト)。メッセージは、retentionプロパティに基づいて、キュー表に保存できます。REMOVE_NO_DATAを指定すると、メッセージは更新済または削除済としてマークされます。

  • navigation

    navigation属性では、デキュー対象メッセージの位置を指定します。FIRST_MESSAGEを指定すると、使用可能で検索基準と一致する最初のメッセージがデキューされます。NEXT_MESSAGEを指定すると、検索基準と一致する次に使用可能なメッセージがデキューされます(デフォルト)。前のメッセージがメッセージ・グループに属する場合は、そのメッセージ・グループに属するメッセージの中から、検索基準に一致する次に使用可能なメッセージがデキューされます。

    NEXT_TRANSACTIONを指定すると、現行のトランザクション・グループ内のメッセージがスキップされ、次のトランザクション・グループの最初のメッセージがデキューされます。この設定を使用できるのは、キューでメッセージのグループ化が可能な場合のみです。

  • visibility

    visibility属性では、新規メッセージのデキュー時期を指定します。ON_COMMITを指定すると、デキューは現行のトランザクションの一部になります(デフォルト)。IMMEDIATEを指定すると、デキュー操作は操作の最後にコミットする自律型トランザクションとなります。visibility属性は、BROWSEデキュー・モードでは無視されます。

    配信モードDBMS_AQ.BUFFEREDまたはDBMS_AQ.PERSISTENT_OR_BUFFEREDでメッセージをデキューする場合は、visibilityを常にIMMEDIATEに設定する必要があります。

  • wait

    wait属性では、検索基準と一致する使用可能なメッセージがない場合の待機時間を指定します。数値を指定すると、操作はその秒数だけ待機します。FOREVERを指定すると、操作は永続的に待機します(デフォルト)。NO_WAITを指定すると、操作は待機しません。

  • msgid

    msgid属性では、デキュー対象メッセージのメッセージ識別子を指定します。msgidを指定しないかぎり、READY状態のメッセージのみがデキューされます。

  • correlation

    correlation属性では、デキュー対象メッセージの相関識別子を指定します。一連のデキュー・コール間では、FIRST_MESSAGEナビゲーション・オプションを指定しないと相関識別子を変更できません。

    相関識別子は、Oracle Streams Advanced Queuingでは解釈されない、アプリケーション定義の識別子です。パーセント記号やアンダースコアなど、特殊なパターン・マッチング文字を使用できます。複数のメッセージがパターンと一致する場合、デキュー順序は不定になり、キューのソート順序は無視されます。


    注意:

    バッファ済メッセージの場合、デキュー・オプションcorrelationおよびdeq_conditionの両方がサポートされますが、索引を作成してこれらの問合せを最適化することはできません。

  • deq_condition

    deq_condition属性は、SQL問合せのWHERE句に似たブール式です。このブール式には、メッセージ・プロパティ、ユーザー・データ・プロパティ(オブジェクト・ペイロードのみ)およびPL/SQLまたはSQLファンクションに関する条件を含めることができます。

    メッセージ・ペイロード(オブジェクト・ペイロード)にデキュー条件を指定するには、句にオブジェクト型の属性を使用します。各属性には、ペイロードを格納するキュー表の特定の列を示す修飾子として、接頭辞tab.user_dataが必要です。

    deq_condition属性は4000文字以内です。複数のメッセージがデキュー条件と一致する場合、デキュー順序は不定になり、キューのソート順序は無視されます。

  • transformation

    transformation属性では、メッセージがデキューされてからコール側に戻されるまでに適用される変換を指定します。

  • delivery_mode

    delivery_mode属性では、デキューするメッセージの型を指定します。DBMS_AQ.PERSISTENTに設定すると、永続メッセージのみがデキューされます。DBMS_AQ.BUFFEREDに設定すると、バッファ済メッセージのみがデキューされます。

    デフォルトのDBMS_AQ.PERSISTENT_OR_BUFFEREDに設定すると、永続メッセージとバッファ済メッセージの両方がデキューされます。デキューされたメッセージのメッセージ・プロパティのdelivery_mode属性は、そのメッセージがバッファ済メッセージであったか永続メッセージであったかを示します。

デキューの順序は、デキュー・オプションのメッセージ識別子および相関識別子でオーバーライドされないかぎり、キュー表の作成時に指定されたソート順によって決定されます。

キュー操作には、データベース読込み一貫性メカニズムが適用されます。たとえば、トランザクションによる参照が始まってからエンキューされたメッセージを、BROWSEコールでは参照できません。

コミット時間キューはOracle Streams Advanced Queuing 10gリリース2(10.2)の新機能であり、近似CSCNに基づいて確定的な順序を確立できないかぎり、BROWSEまたはDEQUEUEのコールではメッセージを参照できません。


関連項目:


dequeue_conditionsパラメータのnavigation属性がNEXT_MESSAGE (デフォルト)の場合、後続のデキューでは、最初のデキューで取得されたスナップショットに基づいて、キューからメッセージが取り出されます。したがって、最初のデキュー・コマンド以降にエンキューされたメッセージは、キューに残っているメッセージがすべて処理された後にのみ処理されます。すべてのメッセージがエンキュー済の場合、またはキューに優先順位ベースの順序が設定されていない場合、これは問題ではありません。ただし、アプリケーションでキューにある最も優先順位の高いメッセージを処理する必要がある場合は、FIRST_MESSAGEナビゲーション・オプションを使用する必要があります。


注意:

同時にエンキューされるメッセージがある場合には、FIRST_MESSAGEナビゲーション・オプションを使用すると効率的です。FIRST_MESSAGEオプションを指定しないと、Oracle Streams Advanced Queuingでは最初のデキュー・コマンドと同様のスナップショットが継続的に生成されるため、パフォーマンスの低下につながります。FIRST_MESSAGEオプションを指定すると、Oracle Streams Advanced Queuingでは、すべてのデキュー・コマンドに新規のスナップショットが使用されます。

メッセージをグループ化できるキューに同一トランザクションのメッセージがエンキューされると、グループが形成されます。トランザクションに1つのメッセージしかエンキューされていない場合でも、事実上1つのグループが形成されます。1つのトランザクションでグループ化できるメッセージの数に、上限はありません。

メッセージをグループ化できないキューでは、LOCKEDまたはREMOVEモードのデキューによって1つのメッセージのみがロックされます。それに対して、グループの一部であるメッセージをデキューする操作では、グループ全体がロックされます。これは、グループのメッセージ全体を1つの単位として処理する必要がある場合に有効です。

グループのメッセージ全体をデキューした後でデキュー操作をすると、グループのすべてのメッセージが処理されたことを示すエラーが戻されます。その後、アプリケーションはNEXT_TRANSACTIONを使用して、次の使用可能なグループからのメッセージのデキューを開始します。使用可能なグループがない場合は、dequeue_optionswait属性で指定した期間が終了するとデキューがタイムアウトになります。

一般的には、メッセージのコンシューマはデキュー・インタフェースによってメッセージにアクセスすると考えられます。処理済または処理が終了していないメッセージは、メッセージIDまたはSELECTコマンドを使用して参照できます。

例10-13では、例10-1でエンキューされたメッセージが戻されます。戻り値は次のとおりです。

From Sender No.1
Subject: TEST MESSAGE
Text: First message to obj_queue

例10-13 オブジェクト型メッセージのデキュー

SET SERVEROUTPUT ON
DECLARE
dequeue_options     DBMS_AQ.dequeue_options_t;
message_properties  DBMS_AQ.message_properties_t;
message_handle      RAW(16);
message             test.message_typ;
BEGIN
   dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
   DBMS_AQ.DEQUEUE(
      queue_name          =>     'test.obj_queue',
      dequeue_options     =>     dequeue_options,
      message_properties  =>     message_properties,
      payload             =>     message,
      msgid               =>     message_handle);
   DBMS_OUTPUT.PUT_LINE('From Sender No.'|| message.sender_id);
   DBMS_OUTPUT.PUT_LINE('Subject: '||message.subject);
   DBMS_OUTPUT.PUT_LINE('Text: '||message.text);
   COMMIT;
END;
/

LOB型メッセージのデキュー

例10-14では、Example 10-4でエンキューされたLOBタイプ・メッセージをデキューするために、blobdequeue()プロシージャを作成します。実際のデキューは例10-15で示されています。戻り値は次のとおりです。

Amount of data read: 2000
Amount of data read: 2000
Amount of data read: 2000
Amount of data read: 2000
Amount of data read: 2000

例10-14 LOB型メッセージのデキュー・プロシージャの作成

CREATE OR REPLACE PROCEDURE blobdequeue(msgno IN NUMBER) AS
   dequeue_options     DBMS_AQ.dequeue_options_t; 
   message_properties  DBMS_AQ.message_properties_t; 
   msgid               RAW(16); 
   payload             test.lob_typ; 
   lob_loc             BLOB; 
   amount              BINARY_INTEGER; 
   buffer              RAW(4096); 
BEGIN 
   DBMS_AQ.DEQUEUE(
      queue_name          =>  'test.lob_queue',
      dequeue_options     =>   dequeue_options, 
      message_properties  =>   message_properties, 
      payload             =>   payload,
      msgid               =>   msgid); 
   lob_loc                :=   payload.data;
   amount                 :=   2000; 
   DBMS_LOB.READ(lob_loc, amount, 1, buffer);
   DBMS_OUTPUT.PUT_LINE('Amount of data read: '|| amount); 
   COMMIT;
END;
/

例10-15 LOB型メッセージのデキュー

BEGIN 
   FOR i IN 1..5 LOOP 
     blobdequeue(i); 
   END LOOP; 
END;
/

グループ化されたメッセージのデキュー

例10-16を実行すると、例10-8でエンキューした、グループ化されたメッセージをデキューできます。戻り値は次のとおりです。

GROUP 1: Message 1 in group 1
GROUP 1: Message 2 in group 1
GROUP 1: Message 3 in group 1
Finished GROUP 1
GROUP 2: Message 1 in group 2
GROUP 2: Message 2 in group 2
GROUP 2: Message 3 in group 2
Finished GROUP 2
GROUP 3: Message 1 in group 3
GROUP 3: Message 2 in group 3
GROUP 3: Message 3 in group 3
Finished GROUP 3
No more messages

例10-16 グループ化されたメッセージのデキュー

SET SERVEROUTPUT ON
DECLARE
   dequeue_options       DBMS_AQ.dequeue_options_t;
   message_properties    DBMS_AQ.message_properties_t;
   message_handle        RAW(16);
   message               test.message_typ;
   no_messages           exception;
   end_of_group          exception;
   PRAGMA EXCEPTION_INIT (no_messages, -25228);
   PRAGMA EXCEPTION_INIT (end_of_group, -25235);
BEGIN
   dequeue_options.wait       := DBMS_AQ.NO_WAIT;
   dequeue_options.navigation := DBMS_AQ.FIRST_MESSAGE;
   LOOP
     BEGIN
     DBMS_AQ.DEQUEUE(
        queue_name         => 'test.group_queue',
        dequeue_options    => dequeue_options,
        message_properties => message_properties,
        payload            => message,
        msgid              => message_handle);
     DBMS_OUTPUT.PUT_LINE(message.subject || ': ' || message.text );
     dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;
     EXCEPTION
       WHEN end_of_group THEN
         DBMS_OUTPUT.PUT_LINE ('Finished ' || message.subject);
         COMMIT;
         dequeue_options.navigation := DBMS_AQ.NEXT_TRANSACTION;
     END;
   END LOOP;
   EXCEPTION
     WHEN no_messages THEN
       DBMS_OUTPUT.PUT_LINE ('No more messages');
END;
/

マルチ・コンシューマ・キューからのデキュー

例10-17を実行すると、例10-7REDについてエンキューしたメッセージをデキューできます。REDGREENに変更し、さらにBLUEに変更すると、それぞれのメッセージのデキューにも使用できます。例の出力は、それぞれ異なります。

REDはマルチ・コンシューマ・キューのサブスクライバで、MESSAGE 2の指定の受信者でもあるため、両方のメッセージを取得します。

Message: MESSAGE 1 .. For queue subscribers
Message: MESSAGE 2 .. For two recipients
No more messages for RED

GREENはサブスクライバにすぎないため、受信者が指定されていないキュー内のメッセージ(この場合はMESSAGE 1)のみを取得します。

Message: MESSAGE 1 .. For queue subscribers
No more messages for GREEN

BLUEはキューのサブスクライバではありませんが、MESSAGE 2の宛先に指定されています。

Message: MESSAGE 2 .. For two recipients
No more messages for BLUE

例10-17 マルチ・コンシューマ・キューからのREDのメッセージのデキュー

SET SERVEROUTPUT ON
DECLARE
  dequeue_options       DBMS_AQ.dequeue_options_t;
  message_properties    DBMS_AQ.message_properties_t;
  message_handle        RAW(16);
  message               test.message_typ;
  no_messages           exception;
  PRAGMA EXCEPTION_INIT (no_messages, -25228);
BEGIN
  dequeue_options.wait          := DBMS_AQ.NO_WAIT;
  dequeue_options.consumer_name := 'RED';
  dequeue_options.navigation    := DBMS_AQ.FIRST_MESSAGE;
  LOOP
   BEGIN
    DBMS_AQ.DEQUEUE(
      queue_name         => 'test.multiconsumer_queue',
      dequeue_options    => dequeue_options,
      message_properties => message_properties,
      payload            => message,
      msgid              => message_handle);
    DBMS_OUTPUT.PUT_LINE('Message: '|| message.subject ||' .. '|| message.text );
    dequeue_options.navigation := DBMS_AQ.NEXT_MESSAGE;
   END;
  END LOOP;
  EXCEPTION
    WHEN no_messages THEN
    DBMS_OUTPUT.PUT_LINE ('No more messages for RED');
  COMMIT;
END;
/

例10-18では、例10-5でエンキューしたメッセージをPINKが見つかるまで参照し、PINKを削除します。この例は、次の行を戻します。

Browsed Message Text: ORANGE enqueued first.
Browsed Message Text: ORANGE also enqueued second.
Browsed Message Text: YELLOW enqueued third.
Browsed Message Text: VIOLET enqueued fourth.
Browsed Message Text: PURPLE enqueued fifth.
Browsed Message Text: PINK enqueued sixth.
Removed Message Text: PINK enqueued sixth.

デキュー・モード

例10-18 参照モードによるデキューと指定のメッセージの削除

SET SERVEROUTPUT ON
DECLARE
   dequeue_options     DBMS_AQ.dequeue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   dequeue_options.dequeue_mode := DBMS_AQ.BROWSE;
   LOOP
      DBMS_AQ.DEQUEUE(
        queue_name              => 'test.obj_queue',
        dequeue_options         => dequeue_options,
        message_properties      => message_properties,
        payload                 => message,
        msgid                   => message_handle);
      DBMS_OUTPUT.PUT_LINE ('Browsed Message Text: ' || message.text);
      EXIT WHEN message.subject = 'PINK';
   END LOOP;
   dequeue_options.dequeue_mode := DBMS_AQ.REMOVE;
   dequeue_options.msgid        := message_handle;
   DBMS_AQ.DEQUEUE(
           queue_name           => 'test.obj_queue',
           dequeue_options      => dequeue_options,
           message_properties   => message_properties,
           payload              => message,
           msgid                => message_handle);
   DBMS_OUTPUT.PUT_LINE('Removed Message Text: ' || message.text);
   COMMIT;
END;
/

例10-19では、例10-5でエンキューしたメッセージをPURPLEが見つかるまでロック・モードでプレビューし、PURPLEを削除します。この例は、次の行を戻します。

Locked Message Text: ORANGE enqueued first.
Locked Message Text: ORANGE also enqueued second.
Locked Message Text: YELLOW enqueued third.
Locked Message Text: VIOLET enqueued fourth.
Locked Message Text: PURPLE enqueued fifth.
Removed Message Text: PURPLE enqueued fifth.

例10-19 ロック・モードによるデキューと指定のメッセージの削除

SET SERVEROUTPUT ON
DECLARE
   dequeue_options     DBMS_AQ.dequeue_options_t;
   message_properties  DBMS_AQ.message_properties_t;
   message_handle      RAW(16);
   message             test.message_typ;
BEGIN
   dequeue_options.dequeue_mode := DBMS_AQ.LOCKED;
   LOOP
      DBMS_AQ.dequeue(
        queue_name         => 'test.obj_queue',
        dequeue_options    => dequeue_options,
        message_properties => message_properties,
        payload            => message,
        msgid              => message_handle);
      DBMS_OUTPUT.PUT_LINE('Locked Message Text: ' || message.text);
      EXIT WHEN message.subject = 'PURPLE';
   END LOOP;
   dequeue_options.dequeue_mode := DBMS_AQ.REMOVE;
   dequeue_options.msgid        := message_handle;
   DBMS_AQ.DEQUEUE(
     queue_name           => 'test.obj_queue',
     dequeue_options      => dequeue_options,
     message_properties   => message_properties,
     payload              => message,
     msgid                => message_handle);
   DBMS_OUTPUT.PUT_LINE('Removed Message Text: ' || message.text);
   COMMIT;
END;
/

関連項目:

OO4Oのメッセージ・デキューの例は、『Oracle Objects for OLE開発者ガイド』のアドバンスト・キューイング・インタフェースの使用に関する項を参照してください。

メッセージの配列のデキュー

DBMS_AQ.DEQUEUE_ARRAY(
   queue_name                IN      VARCHAR2,
   dequeue_options           IN      dequeue_options_t,
   array_size                IN      PLS_INTEGER, 
   message_properties_array  OUT     message_properties_array_t,
   payload_array             OUT     VARRAY,
   msgid_array               OUT     msgid_array_t)
RETURN PLS_INTEGER;

DEQUEUE_ARRAY関数を使用して、ペイロードの配列および対応する配列のメッセージ・プロパティをデキューします。結果には、デキューされたメッセージのペイロードの配列、メッセージIDおよびメッセージ・プロパティが出力されます。また、正常にデキューされたメッセージの数も戻されます。

バッファ済メッセージの場合、配列のデキューはサポートされていませんが、array_size1に設定してDBMS_AQ.DEQUEUE_ARRAY()を使用すると、バッファ済メッセージをデキューできます。

ペイロード構造は、VARRAYまたはネストした表のいずれかです。メッセージ識別子は、DBMS_AQ.msgid_array_t型のRAW(16)のエントリの配列に戻されます。メッセージ・プロパティは、DBMS_AQ.message_properties_array_t型の配列に戻されます。

リレーショナルDB環境における配列操作と同様に、すべての状況に対応可能な1つの最適な配列サイズを指定することはできません。アプリケーション開発者は、様々な配列サイズをテストして、各アプリケーションにとって最適な値を決定する必要があります。

DBMS_AQ.DEQUEUEで使用可能なデキュー・オプションはすべて、DBMS_AQ.DEQUEUE_ARRAYでも使用できます。Oracle Streams Advanced Queuing 10gリリース2(10.2)からは、デキュー対象として永続メッセージのみ、バッファ済メッセージのみ、またはその両方を選択できます。また、dequeue_optionsnavigation属性には、DBMS_AQ.DEQUEUE_ARRAYに固有の2つのオプションが用意されています。

メッセージをデキューするときは、トランザクション・グループのすべてのメッセージを1つのコールでデキューできます。また、複数のトランザクション・グループのメッセージをデキューすることもできます。いずれの方法も、次のナビゲーション・メソッドを使用して指定できます。

  • NEXT_MESSAGE_ONE_GROUP

  • FIRST_MESSAGE_ONE_GROUP

  • NEXT_MESSAGE_MULTI_GROUP

  • FIRST_MESSAGE_MULTI_GROUP

ナビゲーション・メソッドNEXT_MESSAGE_ONE_GROUPは、検索基準と一致したメッセージを次の使用可能なトランザクション・グループから配列にデキューします。ナビゲーション・メソッドFIRST_MESSAGE_ONE_GROUPは、位置をキューの先頭にリセットし、1つのトランザクション・グループから使用可能かつ検索基準と一致するすべてのメッセージをデキューします。

デキューされるメッセージの数は、配列サイズの制限によって決まります。トランザクション・グループ内のメッセージ数がarray_sizeを超えている場合は、複数のDEQUEUE_ARRAYをコールして、そのトランザクション・グループのすべてのメッセージをデキューする必要があります。

ナビゲーション・メソッドNEXT_MESSAGE_MULTI_GROUPおよびFIRST_MESSAGE_MULTI_GROUPは、それぞれのカウンターパートONE_GROUPと同様に機能しますが、1つのトランザクション・グループには制限されません。配列にデキューされる各メッセージには、一連のメッセージ・プロパティが対応付けられています。メッセージ・プロパティtransaction_groupによって、同じトランザクション・グループに属するメッセージが特定されます。

例10-20では、例10-11でエンキューされたメッセージがデキューされます。戻り値は次のとおりです。

Number of messages dequeued: 2

例10-20 メッセージの配列のデキュー

SET SERVEROUTPUT ON
DECLARE
  dequeue_options       DBMS_AQ.dequeue_options_t;
  msg_prop_array        DBMS_AQ.message_properties_array_t := 
                        DBMS_AQ.message_properties_array_t();
  payload_array         test.msg_table;
  msgid_array           DBMS_AQ.msgid_array_t;
  retval                PLS_INTEGER;
BEGIN
  retval := DBMS_AQ.DEQUEUE_ARRAY( 
              queue_name               => 'test.obj_queue',
              dequeue_options          => dequeue_options,
              array_size               => 2,
              message_properties_array => msg_prop_array,
              payload_array            => payload_array,
              msgid_array              => msgid_array);
  DBMS_OUTPUT.PUT_LINE('Number of messages dequeued: ' || retval);
END;/
 

通知の登録

DBMS_AQ.REGISTER(
   reg_list     IN SYS.AQ$_REG_INFO_LIST,
   reg_count    IN NUMBER);

このプロシージャでは、メッセージ通知に使用する電子メール・アドレス、ユーザー定義PL/SQLプロシージャまたはHTTP URLを登録します。


注意:

Oracle Database 10gリリース2(10.2)より前のリリースでは、31文字以上の名前を持つキューの場合、Oracle Streams Advanced Queuingの通知機能はサポートされませんでした。この制限は適用されなくなりました。ユーザー生成キューの名前には、引き続き24文字という制限が適用されます。「キューの作成」を参照してください。

reg_listパラメータは、SYS.AQ$_REG_INFOオブジェクトのリストです。SYS.AQ$_REG_INFOqosflags属性を使用して、サービスの通知品質(Oracle Streams Advanced Queuing 10gリリース2 (10.2)の新機能)を指定できます。


関連項目:

SYS.AQ$_REG_INFOオブジェクトの詳細は、「AQ登録情報型」を参照してください。

reg_countパラメータでは、reg_listのエントリ数を指定します。各サブスクリプションには固有のreg_listエントリが必要です。一度に、複数のサブスクリプションを登録できます。

PL/SQL通知の受信時には、コールバックの起動に使用されるOracle Streams Advanced Queuingメッセージ・プロパティ記述子に通知メッセージのdelivery_modeDBMS_AQ.PERSISTENTまたはDBMS_AQ.BUFFEREDとして指定されます。


関連項目:

メッセージ・プロパティ記述子の詳細は、「AQ通知記述子型」を参照してください。

電子メールによる通知を登録する場合は、データベースで電子メール通知の送信に使用されるSMTPサーバーのホスト名およびポート名を設定する必要があります。必要な場合は、データベースのsentfromフィールドを使用して、発信元の電子メール・アドレスを設定します。この機能を使用するには、Java対応のデータベースが必要です。

HTTP通知を登録した場合は、データベースでHTTP通知の転送に使用されるプロキシ・サーバーのホスト名とポート番号、および非プロキシ・ドメインのリストを設定できます。

ジョブ・キュー・プロセスにより処理される通知は、内部キューSYS.AQ_SRVNTFN_TABLE_Qに格納されます。通知に失敗すると、Oracle Streams Advanced Queuingは失敗した通知を最大でMAX_RETRIES回まで再試行します。


注意:

SYS.AQ_SRVNTFN_TABLE_QMAX_RETRIESおよびRETRY_DELAYプロパティは変更できます。新規の設定はすべての通知に適用されます。

例10-21 通知の登録

DECLARE
  reginfo             sys.aq$_reg_info;
  reg_list            sys.aq$_reg_info_list;
BEGIN
  reginfo := sys.aq$_reg_info(
                      'test.obj_queue',
                      DBMS_AQ.NAMESPACE_ANONYMOUS,
                      'http://www.company.com:8080', 
                      HEXTORAW('FF'));
  reg_list  := sys.aq$_reg_info_list(reginfo);
  DBMS_AQ.REGISTER(
    reg_list     => reg_list, 
    reg_count    => 1);
  COMMIT;
END;
/

通知の登録解除

DBMS_AQ.UNREGISTER(
   reg_list     IN SYS.AQ$_REG_INFO_LIST,
   reg_count    IN NUMBER);

このプロシージャでは、メッセージ通知に使用する電子メール・アドレス、ユーザー定義PL/SQLプロシージャまたはHTTP URLの登録を解除します。

サブスクライバの通知の転送

DBMS_AQ.POST(
  post_list       IN  SYS.AQ$_POST_INFO_LIST,
  post_count      IN  NUMBER);

このプロシージャでは、匿名サブスクリプションのリストに通知を転送し、サブスクリプションに登録する全クライアントが永続メッセージの通知を取得できるようにします。この機能は、バッファ済メッセージについてはサポートされません。

countパラメータでは、post_listのエントリ数を指定します。転送済の各サブスクリプションは、post_list内に固有のエントリを持つ必要があります。一度に、複数のサブスクリプションを転送できます。

post_listパラメータでは、転送する匿名サブスクリプションのリストを指定します。次の3つの属性があります。

  • name

    name属性では、転送する匿名サブスクリプションの名前を指定します。

  • namespace

    namespace属性では、サブスクリプションの名前空間を指定します。DBMS_AQ.POSTを介して他のアプリケーションから通知を受信するには、namespaceをDBMS_AQ.NAMESPACE_ANONYMOUSに設定する必要があります。

  • payload

    payload属性では、匿名サブスクリプションに転送するペイロードを指定します。このコールに関連付けるペイロードがない可能性もあります。

このコールは、最も効果的な転送を保証します。通知は、登録されたクライアントにすぐに届きます。このコールは、主に軽量な通知に使用されます。アプリケーションがより確実な保証を必要とする場合は、キューにエンキューできます。

例10-22 オブジェクト型メッセージの転送

DECLARE
  postinfo            sys.aq$_post_info;
  post_list           sys.aq$_post_info_list;
BEGIN
  postinfo  := sys.aq$_post_info('test.obj_queue',0,HEXTORAW('FF')); 
  post_list := sys.aq$_post_info_list(postinfo);
  DBMS_AQ.POST(
    post_list       => post_list,
    post_count      => 1);
  COMMIT;
END;
/

エージェントのLDAPサーバーへの追加

DBMS_AQ.BIND_AGENT(
   agent        IN SYS.AQ$_AGENT,
   certificate  IN VARCHAR2 default NULL);

このプロシージャは、Lightweight Directory Access Protocol(LDAP)サーバーにOracle Streams Advanced Queuingエージェントのエントリを作成します。

agentパラメータでは、LDAPサーバーに登録するOracle Streams Advanced Queuingエージェントを指定します。

certificateパラメータでは、このエージェントにデジタル証明書(usercertificate属性)を使用するLDAP内のOrganizationalPersonエントリの位置(LDAP識別名)を指定します。たとえば、cn=OE, cn=ACME, cn=comは、指定のエージェントに証明書を使用するOrganizationalPerson OEの識別名です。エージェントがデジタル証明を持たない場合、このパラメータはデフォルトでNULLに設定されます。

エージェントのLDAPサーバーからの削除

DBMS_AQ.UNBIND_AGENT(
   agent    IN SYS.AQ$_AGENT);

このプロシージャでは、LDAPサーバーからOracle Streams Advanced Queuingエージェントのエントリを削除します。