シングルトン・パイプを使用したメッセージのキャッシュ

シングルトン・パイプは、カスタム・メッセージをキャッシュおよび取得し、同時読取りで複数のデータベース・セッション間でメッセージを共有できるようにするDBMS_PIPEパッケージに追加したものです。

シングルトン・パイプを使用したメッセージのキャッシュについて

DBMS_PIPEパッケージには、シングルトン・パイプをサポートするAutonomous AI Databaseの拡張機能があります。

DBMS_PIPEのシングルトン・パイプ:

標準パイプとシングルトンパイプについて

DBMS_PIPEパッケージでは、2つ以上のデータベース・セッションがインメモリー・メッセージを使用して通信できます。パイプ機能には、外部サービス・インタフェース、デバッグ、独立したトランザクション、アラートなどの複数のアプリケーションがあります。詳細は、『Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス』DBMS_PIPEに関する項または『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

図database-pipe-messages-singleton-pipes.pngの説明

シングルトン・パイプは、サポートされているDBMS_PIPEタイプのいずれかです。

シングルトン・パイプは、Autonomous AI Databaseインスタンスのメモリーに単一のメッセージをキャッシュする機能を提供します。

次に、シングルトン・パイプを使用するための一般的なワークフローを示します。

図singleton-pipe-workflow.pngの説明

シングルトンパイプの概要と機能

シングルトンパイプ操作

操作 DBMS_PIPEファンクションまたはプロシージャ
明示的なシングルトン・パイプの作成 CREATE_PIPEファンクション
シングルトン・パイプにメッセージをキャッシュする

『Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス』PACK_MESSAGEプロシージャに関する項または『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』

SEND_MESSAGEファンクション

シングルトン・パイプからのキャッシュされたメッセージの読取り 『Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス』RECEIVE_MESSAGEファンクションUNPACK_MESSAGEプロシージャまたは『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』
シングルトン・パイプでのメッセージの削除 『Oracle Database 19c PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』PURGEプロシージャに関する項または『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』
明示的なシングルトンパイプの削除 『Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス』または『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』REMOVE_PIPEファンクションに関する項

キャッシュ関数を使用したキャッシュ済メッセージの自動リフレッシュ

DBMS_PIPEパッケージを使用すると、ユーザー定義のキャッシュ・ファンクションを使用してシングルトン・パイプ・メッセージを自動的に移入できます。

デフォルトでは、シングルトン・パイプの明示的または暗黙的な無効化によってメッセージが無効化されると、後続のDBMS_PIPE.RECEIVE_MESSAGEではメッセージを受信しません。新しいメッセージをパイプに追加するには、DBMS_PIPE.SEND_MESSAGEをコールしてメッセージを明示的にキャッシュする必要があります。この場合、シングルトンパイプから読み取るときにメッセージを使用できないことを回避するために、キャッシュ関数を定義できます。キャッシュ関数を定義すると、次のシナリオでメッセージを受信すると、キャッシュ関数が自動的に呼び出されます。

キャッシュ関数を使用するには、キャッシュ関数を定義し、cache_funcパラメータをDBMS_PIPE.RECEIVE_MESSAGEに含めます。ユーザー定義キャッシュ関数には、次の機能があります。

キャッシュ関数を使用すると、シングルトン・パイプの操作が簡略化されます。空のパイプからメッセージを受信するための障害ケースを処理する必要はありません。また、キャッシュ関数は、シングルトンパイプからメッセージを読み取るときにキャッシュミスがないことを確認し、キャッシュされたメッセージを最大限に活用します。

automatic-cache-refresh-cache-function.epsの説明が続きます

図automatic-cache-refresh-cache-function.pngの説明

キャッシュ関数を定義する場合、関数名は所有者スキーマで完全修飾される必要があります。

次のシグネチャを使用してキャッシュ関数を定義します。

CREATE OR REPLACE FUNCTION *cache_function_name*(
       pipename  IN VARCHAR2
) RETURN INTEGER;

キャッシュ・ファンクションでの一般的な操作は次のとおりです。

キャッシュ・ファンクションを使用するには、DBMS_PIPE.RECEIVE_MESSAGEを起動する現在のセッション・ユーザーに、キャッシュ・ファンクションの実行に必須の権限が必要です。

キャッシュ関数の定義の詳細は、「RECIEVE_MESSAGE関数」を参照してください。

明示的なシングルトン・パイプの作成

指定されたパイプ名(明示的なシングルトン・パイプ)でシングルトン・パイプを作成するステップについて説明します。

まず、この例では、DBMS_PIPE.RECEIVE_MESSAGEを繰り返しコールするreceive_messageヘルパー関数を作成します。これにより、シングルトンパイプ機能をテストできます。

CREATE OR REPLACE FUNCTION msg_types AS
       TYPE t_rcv_row IS RECORD (c1 VARCHAR2(32767), c2 NUMBER);
       TYPE t_rcv_tab IS TABLE OF t_rcv_row;
END;


CREATE OR REPLACE FUNCTION receive_message(
      pipename    IN VARCHAR2,
      rcv_count   IN NUMBER DEFAULT 1,
      cache_func  IN VARCHAR2 DEFAULT NULL)
   RETURN msg_types.t_rcv_tab pipelined
    AS
       l_msg    VARCHAR2(32767);
       l_status NUMBER;
 BEGIN
      FOR i IN 1..rcv_count LOOP
           l_status := DBMS_PIPE.RECEIVE_MESSAGE(
            pipename   => pipename,
            cache_func => cache_func,
            timeout    => 1);
         IF l_status != 0 THEN
              raise_application_error(-20000,
             'Message not received for attempt: ' || to_char(i) || ' status: ' ||
            l_status);
         END IF;

         DBMS_PIPE.UNPACK_MESSAGE(l_msg);
             pipe row(msg_types.t_rcv_row(l_msg));
     END LOOP;
 RETURN;
 END;
  1. shelflifeパラメータを3600 (秒)に設定して、PIPE_TESTという名前の明示的なシングルトン・パイプを作成します。

      DECLARE
      l_status INTEGER;
      BEGIN
      l_status := DBMS_PIPE.CREATE_PIPE(
                    pipename => 'MY_PIPE1',
                    private => TRUE,
                    singleton => TRUE,
                    shelflife => 3600);
      END;
      /

    詳細は、「CREATE_PIPEファンクション」を参照してください。

  2. シングルトン・パイプが作成されていることを確認します。

    SELECT name, singleton, type
         FROM v$db_pipes WHERE name= '&pipename' ORDER BY 1;
    NAME                 SINGLETON  TYPE
    
    -------------------- ---------- -------
    PIPE_TEST            YES        PRIVATE
  3. シングルトンパイプにメッセージをパックして送信します。

    EXEC DBMS_PIPE.PACK_MESSAGE('This is a real message that you can get multiple times');
    
    SELECT DBMS_PIPE.SEND_MESSAGE(pipename => '&pipename') status FROM DUAL;
    STATUS
    
    ----------
    0

    詳細は、Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンスPACK_MESSAGEプロシージャ、またはOracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンスおよびSEND_MESSAGEファンクションを参照してください。

  4. シングルトンパイプからメッセージを受信します。

     SELECT * FROM receive_message(
         pipename => '&pipename',
         rcv_count => 2);
     MESSAGE
    
     --------------------------------------------------------------------------------
     This is a real message that you can get multiple times
     This is a real message that you can get multiple times

    receive_message関数は、DBMS_PIPE.RECEIVE_MESSAGEをコールするヘルパー関数です。

  5. メッセージをパージし、パイプを取り外します。

    EXEC DBMS_PIPE.PURGE('&pipename');
    SELECT DBMS_PIPE.REMOVE_PIPE('&pipename') status FROM DUAL;

キャッシュ関数を使用した明示的なシングルトン・パイプの作成

指定したパイプ名、明示的なシングルトン・パイプを使用してシングルトン・パイプを作成し、キャッシュ機能を提供するステップについて説明します。キャッシュ機能を使用すると、メッセージをシングルトン・パイプに自動的に移入できます。

  1. キャッシュ関数test_cache_messageをシングルトン・パイプ用に作成します。

    CREATE OR REPLACE FUNCTION test_cache_message(
         pipename IN VARCHAR2) return NUMBER
    
    AS
       l_status NUMBER;
       l_data VARCHAR2(4000);
    BEGIN
       l_status := DBMS_PIPE.CREATE_PIPE(
              pipename => pipename,
              private => TRUE,
              singleton => true,
              shelflife => 600);
       IF l_status != 0 THEN RETURN l_status;
       END IF;
    
       DBMS_PIPE.PACK_MESSAGE('This is a placeholder cache message for an empty pipe');
       l_status := DBMS_PIPE.SEND_MESSAGE(pipename => pipename);
       RETURN l_status;
     END;
    /

    ノート: DBMS_PIPE.RECEIVE_MESSAGEを起動する現在のセッション・ユーザーには、キャッシュ機能を実行するために必要な権限が必要です。

  2. キャッシュ関数で受信し、メッセージがパイプに移入されることを確認します。パイプは、キャッシュ関数で作成されたプライベートパイプとして存在する必要があります。

    SELECT * FROM receive_message(
         pipename => '&pipename',
         rcv_count => 1,
         cache_func => 'TEST_CACHE_MESSAGE');
    MESSAGE
    
    ---------------
    This is a placeholder cache message for an empty pipe

    receive_message関数は、DBMS_PIPE.RECEIVE_MESSAGEをコールするヘルパー関数です。receive_message定義については、明示的なシングルトン・パイプの作成を参照してください。

    詳細は、「CREATE_PIPEファンクション」を参照してください。

  3. パイプにメッセージが残っていることを確認するために、キャッシュ機能なしで受信します。

    SELECT * FROM receive_message(
         pipename => '&pipename',
         rcv_count => 2);
    MESSAGE
    
    ---------------
    This is a placeholder cache message for an empty pipe
    This is a placeholder cache message for an empty pipe

    receive_message関数は、DBMS_PIPE.RECEIVE_MESSAGEをコールするヘルパー関数です。receive_message定義については、明示的なシングルトン・パイプの作成を参照してください。

    詳細は、「CREATE_PIPEファンクション」を参照してください。