DBMS_PIPE自体はオラクル・データベースに古くから提供されているパッケージのようですが、私は使うのは初めてです。これまでは単一インスタンス内で共有メモリを介したメッセージのやり取りだけが可能でした。
Autonomous Databaseの23aiでは、メッセージの保存先にオブジェクト・ストレージのバケットを指定することにより、異なるインスタンス間でのメッセージのやり取りができるようになりました。
以下のように動作する簡単なAPEXアプリケーションを作ってみました。異なるインスタンスで同じAPEXアプリケーションを実行し、メッセージをやり取りしています。
実装するにあたって、以下のオラクルのドキュメントを参考にしています。
また、以下の記事も参考にしました。ただし、以下の記事では、セットアップが完了していません。実装中にこの記事と同じエラー(ORA-20404)が発生したのですが、何故か、エラーが発生しなくなりました。今の所、回避手順は不明です。バケット内にlockファイルが無いというエラーだったのですが、バケット内にlockファイルは残っていて、それを手作業で消したのが良かったのかもしれません。
Persistent, cross database and cross region pipe in Oracle Database 23ai
https://technology.amis.nl/oracle/persistent-cross-database-and-cross-region-pipe-in-oracle-database-23ai/
以下より実装手順を紹介します。
アプリケーションを作る前に、DBMS_PIPEでメッセージのやり取りを行うための準備をします。
https://technology.amis.nl/oracle/persistent-cross-database-and-cross-region-pipe-in-oracle-database-23ai/
以下より実装手順を紹介します。
アプリケーションを作る前に、DBMS_PIPEでメッセージのやり取りを行うための準備をします。
APEXのワークスペース・スキーマはデフォルトではパッケージDBMS_CLOUDとDBMS_PIPEの実行権限を持っていないため、ユーザーADMINでGRANT文を実行し、権限を付与します。
grant execute on dbms_cloud to <APEXワークスペース・スキーマ>;
grant execute on dbms_pipe to <APEXワークスペース・スキーマ>;
続いて、オブジェクト・ストレージにバケットを作成します。今回の例ではpipeというバケットを作成しています。バケットのURLは以下のようになります。バケット名が異なる場合は、pipeの部分を変更します。
https://[ネームスペース].objectstorage.[リージョン].oci.customer-oci.com/n/[ネームスペース]/b/pipe/o/
APEXからOCIオブジェクト・ストレージを操作する(1) - APIユーザーの作成
APIキーの追加時に取得したuser_ocid、tenancy_ocid、private_key、fingerprintの情報より、DBMS_CLOUD.CREATE_CREDENTIALを呼び出し、データベースにクリデンシャルを作成します。以下の例ではcredential_nameをORACLE_API_AGENTとしています。
あらかじめ、パブリック・パイプのPIPE_C2Pを作成します。
declare
l_status INTEGER;
begin
l_status := DBMS_PIPE.CREATE_PIPE(
pipename => 'PIPE_C2P'
,private => false
);
end;
空のAPEXアプリケーションを作成します。名前はSample DBMS_PIPEとします。
メッセージのやり取りは、ホーム・ページに実装します。
アプリケーション定義の置換として、クリデンシャル、バケット、パイプの名前を設定します。
クリデンシャルは置換文字列CREDENTIAL_NAME、バケットはBUCKET_URL、パイプはPIPE_NAMEの置換値として設定します。
ホーム・ページには2つのボタンSEND_MESSAGEとRECEIVE_MESSAGE、それとメッセージを入力するテキスト領域のページ・アイテムP1_MESSAGEを配置します。
ボタンRECEIVE_MESSAGEを押したときに実行されるプロセスとしてReceive Messageを作成し、以下のコードを記述します。
双方ともAutonomous Databaseの場合、インスタンス間での通信手段は他にもあります。データベース・リンクを経由したDBMS_AQによる通信は、DBMS_PIPEよりも高機能です。
DBMS_CLOUDパッケージを導入することで、オンプレの23aiともメッセージのやり取りができるかと考えて試してみましたが、できませんでした。オンプレ版のデータベースへのDBMS_CLOUDのインストールはサポートのドキュメントHow To Setup And Use DBMS_CLOUD Package (ドキュメントID 2748362.1)で紹介されていますが、 「This package is supported in Oracle Database 19c beginning with 19.9 and in Oracle Database 21c beginning with 21.3.」となっていて、23が含まれていません。そのあたりに問題がありそうです。
今回作成したAPEXアプリケーションのエクスポートを以下に置きました。
https://github.com/ujnak/apexapps/blob/master/exports/sample-dbms-pipe.zip
Oracle APEXのアプリケーション作成の参考になれば幸いです。
完