シングルトン・パイプを使用したメッセージのキャッシュ
シングルトン・パイプは、カスタム・メッセージをキャッシュおよび取得し、同時読取りで複数のデータベース・セッション間でメッセージを共有できるようにするDBMS_PIPEパッケージに追加したものです。
シングルトン・パイプを使用したメッセージのキャッシュについて
DBMS_PIPEパッケージには、シングルトン・パイプをサポートするAutonomous AI Databaseの拡張機能があります。
DBMS_PIPEのシングルトン・パイプ:
-
シングルトン・パイプ・メッセージを使用したカスタム・データのインメモリー・キャッシュを提供します。
-
最大32,767バイトのカスタム・メッセージをキャッシュおよび取得する機能をサポートします。
-
同時読取りで複数のデータベース・セッション間でキャッシュされたメッセージの共有をサポートします。これにより、高いスループットが得られ、データベース・セッション間のメッセージの同時読取りがサポートされます。
-
読取り専用データベースおよび読取り/書込みデータベースをサポートします。
-
いくつかのキャッシュ無効化メソッドをサポートします。
-
ユーザーが制御する明示的なキャッシュ無効化。
-
ユーザー指定の時間間隔(秒)後のキャッシュ無効化。この無効化メソッドは、メッセージ・リーダーではなく
shelflifeパラメータを使用して、メッセージ・センダーによって制御されます。これにより、リーダーによるキャッシュの誤った使用による一般的な落とし穴が回避されます。
-
標準パイプとシングルトンパイプについて
DBMS_PIPEパッケージでは、2つ以上のデータベース・セッションがインメモリー・メッセージを使用して通信できます。パイプ機能には、外部サービス・インタフェース、デバッグ、独立したトランザクション、アラートなどの複数のアプリケーションがあります。詳細は、『Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス』のDBMS_PIPEに関する項または『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』を参照してください。

図database-pipe-messages-singleton-pipes.pngの説明
シングルトン・パイプは、サポートされているDBMS_PIPEタイプのいずれかです。
-
暗黙的パイプ:
DBMS_PIPE.SEND_MESSAGE関数を使用して不明なパイプ名でメッセージが送信されると、自動的に作成されます。 -
明示パイプ:ユーザー指定のパイプ名を持つ
DBMS_PIPE.CREATE_PIPEファンクションを使用して作成されます。 -
パブリック・パイプ:
DBMS_PIPEパッケージに対するEXECUTE権限を持つすべてのユーザーがアクセスできます。 -
プライベート・パイプ:パイプ作成者と同じユーザーを持つセッションからアクセスできます。
シングルトン・パイプは、Autonomous AI Databaseインスタンスのメモリーに単一のメッセージをキャッシュする機能を提供します。
次に、シングルトン・パイプを使用するための一般的なワークフローを示します。

図singleton-pipe-workflow.pngの説明
シングルトンパイプの概要と機能
-
シングルトン・メッセージ
-
シングルトンパイプは、パイプに1つのメッセージをキャッシュできるため、「シングルトン」という名前になります。
-
シングルトン・パイプ内のメッセージは、合計メッセージ・サイズが32,767バイトまでの複数のフィールドで構成できます。
-
DBMS_PIPEは、DBMS_PIPE.PACK_MESSAGEプロシージャを使用することで、メッセージ内に複数の属性をパックする機能をサポートしています。 -
パブリック・シングトン・パイプの場合は、
DBMS_PIPEパッケージに対する実行権限がある任意のデータベース・セッションがメッセージを受信できます。 -
「プライベート・シングルトン・パイプ」の場合、メッセージはシングルトン・パイプの作成者と同じユーザーのセッションが受信できるようになります。
-
-
読取りのメッセージ・スループットが高い
-
シングルトン・パイプ(Singleton Pipes)は、無効化されるかパージされるまでパイプにメッセージをキャッシュします。データベース・セッションは、シングルトン・パイプからメッセージを同時に読み取ることができます。
-
シングルトンパイプからメッセージを受信することは、非ブロッキング操作です。
-
-
メッセージ・キャッシュ
-
メッセージは、
DBMS_PIPE.SEND_MESSAGEを使用してシングルトン・パイプにキャッシュされます。 -
シングルトン・パイプにキャッシュされた既存のメッセージがある場合、
DBMS_PIPE.SEND_MESSAGEは前のメッセージを上書きして、シングルトン・パイプに1つのメッセージのみを保持します。
-
-
メッセージ無効化
-
明示的な無効化: プロシージャ
DBMS_PIPE.PURGEを使用してパイプをパージするか、DBMS_PIPE.SEND_MESSAGEを使用してメッセージを上書きしてパイプをパージします。 -
自動無効化: 指定した
shelflife時間が経過すると、メッセージを自動的に無効化できます。
-
-
データベース・メモリーからの削除なし
-
シングルトン・パイプはOracle Databaseのメモリーから削除されません。
-
明示シングルトン・パイプは、
DBMS_PIPE.REMOVE_PIPEを使用して削除されるか、データベースが再起動されるまで、データベース・メモリーに常駐し続けます。 -
暗黙的シングルトン・パイプは、パイプにキャッシュされたメッセージが1つになるまでデータベース・メモリーに存在します。
-
シングルトンパイプ操作
| 操作 | DBMS_PIPEファンクションまたはプロシージャ |
|---|---|
| 明示的なシングルトン・パイプの作成 | CREATE_PIPEファンクション |
| シングルトン・パイプにメッセージをキャッシュする | 『Oracle Database 19c PL/SQLパッケージおよびタイプ・リファレンス』のPACK_MESSAGEプロシージャに関する項または『Oracle Database 26ai PL/SQLパッケージおよびタイプ・リファレンス』 |
| シングルトン・パイプからのキャッシュされたメッセージの読取り | 『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をコールしてメッセージを明示的にキャッシュする必要があります。この場合、シングルトンパイプから読み取るときにメッセージを使用できないことを回避するために、キャッシュ関数を定義できます。キャッシュ関数を定義すると、次のシナリオでメッセージを受信すると、キャッシュ関数が自動的に呼び出されます。
-
シングルトンパイプが空の場合。
-
shelflife時間が経過したためにシングルトン・パイプ内のメッセージが無効な場合。
キャッシュ関数を使用するには、キャッシュ関数を定義し、cache_funcパラメータをDBMS_PIPE.RECEIVE_MESSAGEに含めます。ユーザー定義キャッシュ関数には、次の機能があります。
-
キャッシュ関数は、
DBMS_PIPE.RECEIVE_MESSAGEを使用してシングルトン・パイプからメッセージを読み取るときに指定できます。 -
シングルトン・パイプにメッセージがない場合、
DBMS_PIPE.RECEIVE_MESSAGEはキャッシュ関数を呼び出します。 -
メッセージの
shelflife時間が経過すると、データベースによって新しいメッセージがシングルトン・パイプに自動的に移入されます。
キャッシュ関数を使用すると、シングルトン・パイプの操作が簡略化されます。空のパイプからメッセージを受信するための障害ケースを処理する必要はありません。また、キャッシュ関数は、シングルトンパイプからメッセージを読み取るときにキャッシュミスがないことを確認し、キャッシュされたメッセージを最大限に活用します。

図automatic-cache-refresh-cache-function.pngの説明
キャッシュ関数を定義する場合、関数名は所有者スキーマで完全修飾される必要があります。
-
OWNER.FUNCTION_NAME -
OWNER.PACKAGE.FUNCTION_NAME
次のシグネチャを使用してキャッシュ関数を定義します。
CREATE OR REPLACE FUNCTION *cache_function_name*(
pipename IN VARCHAR2
) RETURN INTEGER;
キャッシュ・ファンクションでの一般的な操作は次のとおりです。
-
DBMS_PIPE.CREATE_PIPEを使用して、明示的なパイプ用のシングルトン・パイプを作成します。 -
シングルトン・パイプラインにキャッシュするメッセージの作成。
-
キャッシュ関数で指定されたパイプにメッセージを送信し、オプションで暗黙メッセージに
shelflifeを指定します。
キャッシュ・ファンクションを使用するには、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;
-
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ファンクション」を参照してください。
-
シングルトン・パイプが作成されていることを確認します。
SELECT name, singleton, type FROM v$db_pipes WHERE name= '&pipename' ORDER BY 1;NAME SINGLETON TYPE -------------------- ---------- ------- PIPE_TEST YES PRIVATE -
シングルトンパイプにメッセージをパックして送信します。
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ファンクションを参照してください。
-
シングルトンパイプからメッセージを受信します。
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 timesreceive_message関数は、DBMS_PIPE.RECEIVE_MESSAGEをコールするヘルパー関数です。 -
メッセージをパージし、パイプを取り外します。
EXEC DBMS_PIPE.PURGE('&pipename'); SELECT DBMS_PIPE.REMOVE_PIPE('&pipename') status FROM DUAL;
キャッシュ関数を使用した明示的なシングルトン・パイプの作成
指定したパイプ名、明示的なシングルトン・パイプを使用してシングルトン・パイプを作成し、キャッシュ機能を提供するステップについて説明します。キャッシュ機能を使用すると、メッセージをシングルトン・パイプに自動的に移入できます。
-
キャッシュ関数
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を起動する現在のセッション・ユーザーには、キャッシュ機能を実行するために必要な権限が必要です。 -
キャッシュ関数で受信し、メッセージがパイプに移入されることを確認します。パイプは、キャッシュ関数で作成されたプライベートパイプとして存在する必要があります。
SELECT * FROM receive_message( pipename => '&pipename', rcv_count => 1, cache_func => 'TEST_CACHE_MESSAGE');MESSAGE --------------- This is a placeholder cache message for an empty pipereceive_message関数は、DBMS_PIPE.RECEIVE_MESSAGEをコールするヘルパー関数です。receive_message定義については、明示的なシングルトン・パイプの作成を参照してください。詳細は、「CREATE_PIPEファンクション」を参照してください。
-
パイプにメッセージが残っていることを確認するために、キャッシュ機能なしで受信します。
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 pipereceive_message関数は、DBMS_PIPE.RECEIVE_MESSAGEをコールするヘルパー関数です。receive_message定義については、明示的なシングルトン・パイプの作成を参照してください。詳細は、「CREATE_PIPEファンクション」を参照してください。