| Oracle Database アプリケーション開発者ガイド-基礎編 10gリリース2(10.2) B19248-02 |
|
この項の内容は次のとおりです。
データベース変更通知とは、クライアント・アプリケーションで問合せをデータベースに登録し、その問合せに関連付けられたオブジェクトのDML変更またはDDL変更に応答して通知を受信できるようにする機能です。通知は、DMLまたはDDLトランザクションのコミット時にデータベースから公開されます。
登録時に、アプリケーションでは通知ハンドラを指定して、重要な問合せのセットを通知ハンドラに関連付けます。通知ハンドラには、サーバー側PL/SQLプロシージャまたはクライアント側Cコールバックを使用できます。登録は、問合せの実行中に参照されるオブジェクトすべてに作成されます。通知ハンドラは、以降にトランザクションにより登録済オブジェクトのいずれかが変更され、コミットされる時点で起動されます。
アプリケーションが、HR.EMPLOYEES表の問合せに対する結果セットの変更について通知を受け取る必要があるとします。 アプリケーションでは、変更通知機能を使用してhr.employees表の問合せをデータベースに登録できます。ユーザーが従業員を追加する場合、アプリケーションでは表に新規行が追加されるときにデータベース変更通知を受信できます。hr.employeesの新規問合せでは、変更後の結果セットが戻されます。
データベースでは、変更通知の発行時に次の一部またはすべての情報を含めることができます。
hr.employees表が変更されたことを示すことができます。
INSERT、UPDATE、DELETE、ALTER TABLEまたはDROP TABLEのいずれによるものであるかを示すことができます。
ROWIDおよび変更したDMLのタイプ。
STARTUPおよびSHUTDOWNなどのグローバル・イベント(一貫性のみ)。Real Application Clustersでは、データベースの最初のインスタンスの起動時または最後のインスタンスの停止時に、通知が配信されます。
通知には、変更があったデータ自体ではなく、変更があった行またはオブジェクトのメタデータのみが含まれます。たとえば、5000から6000への月給の増額があっても、データベースからクライアントには通知されません。変更があったオブジェクトまたは行の最新の値を取得するには、クライアントは通知に含まれていた情報に基づいてデータベースを問い合せる必要があります。
データベース変更通知が有用なのは、データベースへのネットワーク・ラウンドトリップを回避するために、中間層にあってほとんど読取り専用のオブジェクトに対する問合せ結果セットをキャッシュするアプリケーションの場合です。この種のアプリケーションでは、変更通知サービスを使用して、キャッシュ内の重要な問合せについて登録を作成できます。登録した問合せ内で参照されるオブジェクトに変更があると、基礎となるトランザクションのコミット時にデータベースから変更通知が公開されます。この通知に応答して、アプリケーションでは問合せを再実行してキャッシュをリフレッシュできます。
たとえば、Webフォーラム・アプリケーションのユーザーは、バックエンド・データベースに挿入された新規のコンテンツを挿入直後に参照しなくてもよい場合があります。この種のアプリケーションの場合、本質的にデータが少し古いものであっても問題はないため、中間層でキャッシュするとメリットが得られます。このような使用例では、データベース変更通知を使用するとキャッシュをバックエンド・データベースで常に更新できます。
データベース変更通知は多数の開発コンテキストに関係しますが、特に役立つのはキャッシュ内のデータに依存する中間層アプリケーションの場合です。図13-1に、中間層でキャッシュされたデータがバックエンドのOracle Databaseで処理されてから、インターネットを介してアクセスされる標準的な使用例を示します。
中間層のアプリケーションは、キャッシュをデータベースと相対でできるかぎり最新の状態に保ちつつ、データベース・オブジェクトのキャッシュ・コピーに迅速にアクセスする必要があります。キャッシュ・データは、トランザクションにより変更されてコミットされると古くなるか失効するため、アプリケーションは不正な結果にアクセスする危険性があります。アプリケーションがデータベース変更通知を使用している場合は、登録済オブジェクトに変更が発生した時点でOracle Databaseは変更内容の詳細を使用して通知を公開できます。この通知に応答して、アプリケーションではキャッシュ・データをバックエンド・データベースからフェッチしてリフレッシュできます。
図13-2に、中間層のWebクライアントが変更を受信して通知を処理できるプロセスを示します。
図13-2の各ステップの内容は次のとおりです。
HR.EMPLOYEESの問合せの結果セットをキャッシュしているものとします。開発者は、変更通知PL/SQLインタフェースを使用してHR.EMPLOYEESの問合せに関する登録を作成します。また、通知を処理するPL/SQLストアド・プロシージャを作成し、サーバー側PL/SQLプロシージャを通知ハンドラとして提供します。
hr.employees表の1行を更新します。中間層でキャッシュされていたhr.employeesのデータは失効になります。
JOBQバックグラウンド・プロセスが、新規の変更通知メッセージに関する通知を受け取ります。
JOBQプロセスにより、クライアント・アプリケーションから指定されたストアド・プロシージャが実行されます。この例では、JOBQからサーバー側PL/SQLプロシージャにデータが渡されます。PL/SQLコールバック・プロシージャの実装により、通知の処理方法が決まります。
hr.employees内で変更された行のROWIDをアプリケーションに通知します。
この項の内容は次のとおりです。
ユーザーが変更通知に対する登録を作成するには、CHANGE NOTIFICATIONシステム権限が必要です。また、登録するすべてのオブジェクトに対するSELECT権限も必要です。登録の作成時にはオブジェクトに対するSELECT権限が付与されていても、それ以降に(取消しにより)権限を失った場合は、登録がパージされ、それを反映した通知が公開されることに注意してください。
データベース変更登録は、概念上(受信者R、問合せリストQL)の1組とみなすことができます。問合せリストに含まれる問合せで参照されるオブジェクトのいずれかに変更が発生すると、受信者が通知を受信します。受信者には、サーバー側PL/SQLストアド・プロシージャまたはクライアント側Cコールバックを使用できます。作成された登録は、Oracleデータベースに永続エンティティとして格納されます。このエンティティは、Oracle Real Application Clustersのすべてのインスタンスが参照できます。トランザクションによりクラスタのいずれかのインスタンス内で登録済オブジェクトが変更されると、通知が生成されます。作成された登録は、クライアント・アプリケーションが明示的に登録を解除するか、タイムアウトになるか、またはデータベースがなんらかの理由(権限の消失など)で暗黙的に削除するまで存続します。
データベース・セッションでCHANGE NOTIFICATION権限が付与されている場合は、次の手順で問合せを登録して通知を受信できます。
変更通知登録はデフォルトで永続的であり、アプリケーションで明示的に解除するまで存続します。
登録が正常に作成された後は、基礎となるトランザクションのコミット時に、登録済問合せで参照されるオブジェクトに変更があると、それに応答してOracle Databaseからクライアント・アプリケーションに通知されます。通知は、INSERT、UPDATEおよびDELETE(トランザクションのコミット時)などのDML操作と、ALTERおよびDROPなどのDDL操作の結果として生成されます。
通知には、変更されたオブジェクトの名前、変更を行ったトランザクションのトランザクションIDおよび操作のTYPE(INSERT、UPDATEまたはDELETE)の情報が含まれます。
変更通知により、アプリケーションはストアド・プロシージャやREFカーソルの一部として実行される問合せなど、ほとんどの問合せタイプを登録できます。登録の実行時に、アプリケーションは問合せのみを実行します。つまり、DML操作やDDL操作は許可されません。また、次のタイプの問合せは、登録ではサポートされません。
Oracle Databaseでは、次のオブジェクト登録オプションがサポートされています。
ROWID」オプション: 変更された行のROWIDは、通知の「ROWID」オプションの一部です。
INSERTおよびUPDATEのみに関する通知など)。
「ROWID」オプションを選択した場合は、変更された行のROWIDが通知の一部として公開されます。ROWIDは、外部文字列形式で公開されます。その後、アプリケーションでは、通知に含まれるROWID情報に基づいて、SELECT * from table_name_from_notification where ROWID = rowid_from_notification形式の問合せを実行し、変更された行の内容を取得できる必要があります。ROWIDの長さは、通常のヒープ表の場合は18バイトです。索引構成表(IOT)の場合、ROWIDの長さは主キーのサイズに応じて異なるため、18バイトよりも長くなることがあります。
ROWID通知は階層形式で要約されます。サーバー側がメモリー不足のためにROWIDを保持できないと、通知はFULL-TABLE-NOTIFICATIONにロールアップされる場合があります(そのために通知記述子内の特殊フラグが予約されています)。このような通知を受信した場合、アプリケーションでは表全体(つまりすべての行)が変更された可能性があるものと想定する必要があります。この種の通知には、ROWIDは含まれていません。ROWIDが原因で共有メモリーの使用量合計が大きくなりすぎる(動的共有プール・サイズの1%を超える)場合、1回のトランザクションで1つの登録済オブジェクト内で変更された行数が多すぎる場合(約80行以上)、またはIOTについて変更された行の論理ROWIDの合計長が大きすぎる(約1800バイトを超える)場合は、ROWIDがロールアップされることがあります。
表が削除されると、DROP NOTIFICATIONが公開されます。削除された表に登録があると、そのオブジェクトから対象が暗黙的に削除されます(存在しなくなるため)。この種の登録の対象が他のオブジェクトにも存在する場合、その登録は引き続き存在し、問題のオブジェクトに対するDMLトランザクションのコミット時には引き続き通知が発行されます。削除された表が特定の登録の対象となる唯一のオブジェクトであっても、引き続き登録は保持されます。登録を作成したユーザーは、以降にその登録を他のオブジェクトや問合せの追加に使用できます。
登録は、問合せの登録時点におけるオブジェクトのバージョンと定義に基づきます。オブジェクトが削除されると、そのオブジェクトに対する登録の対象はオブジェクトから永続的に失われます。その後は、同じスキーマ内で一致する名前を使用して別のオブジェクトが作成されても、新規に作成されたオブジェクトは既存のデータベース変更通知登録の目的では新規オブジェクトとなります。つまり、この新規に(同じスキーマおよび名前で)作成されたオブジェクトに変更があっても、オブジェクトの前バージョンに存在していた登録に関する通知は公開されません。
PL/SQLとOCIの両方で登録インタフェースを使用できます。
PL/SQL APIを使用して登録ブロックを定義できます。PL/SQL通知ハンドラなどの登録プロパティは、登録ブロックの開始フェーズで指定します。登録ブロック内で実行される問合せは重要な問合せとみなされ、その問合せで参照されるオブジェクトが登録に追加されます。登録は、登録ブロックの終了時に完了します。PL/SQLでは、DBMS_CHANGE_NOTIFICATIONパッケージを使用して変更通知の受信登録を行います。
OCI Registration APIでは、DBCHANGEという名前空間で関数OCISubscriptionRegisterを起動する必要があります。クライアント側のC通知コールバックなどの登録プロパティは、サブスクリプション・ハンドルの属性として指定します。OCISubscriptionRegisterからの戻り時に、データベースにエンドポイント登録が正常に作成されます。これにより、アプリケーションではその登録に複数の問合せを関連付けることができます。そのためには、サブスクリプション・ハンドルを文ハンドルの属性の1つとして移入します。文ハンドルに関連付けられているDBCHANGE名前空間にサブスクリプション・ハンドルがある場合、オブジェクトの登録は文の実行中、つまりOCIStmtExecuteコールの一部として発生します。
登録済オブジェクトの変更に応答してデータベース・サーバーにより起動されるPL/SQLストアド・プロシージャを作成できます。通知を受信するプロシージャには次のシグネチャが必要です。schema_nameはデータベース・スキーマ名、proc_nameはストアド・プロシージャ名です。
PROCEDURE schema_name.proc_name( ntfnds IN SYS.CHNF$_DESC )
JOBQプロセスは、コールバック・プロシージャにCHNF$_DESCオブジェクト(通知記述子)を渡します。このオブジェクトの属性で変更の詳細が記述されます。たとえば、オブジェクトにはトランザクションID、発生した変更のタイプ、変更された表などが含まれます。コールバック・プロシージャは、このデータを中間層クライアント・アプリケーションに送信し、そこでさらに処理できます。
|
関連項目
|
変更通知を受信する必要のあるデータベース問合せを登録する必要があります。登録は、次の2つの手順で行います。
CHNF$_REG_INFOオブジェクトを作成します。
DBMS_CHANGE_NOTIFICATIONパッケージ内でプログラム・ユニットを実行して問合せ登録を作成または更新してから、登録対象の問合せを実行します。
CHNF$_REG_INFOタイプのオブジェクトでは、登録済オブジェクトのいずれかに変更があった場合にデータベースで実行する必要のあるコールバック・プロシージャを指定します。タイプ属性は、SQL*Plusで次のコマンドを実行して表示できます。
DESC SYS.CHNF$_REG_INFO
表13-1に、SYS.CHNF$_REG_INFOの属性を示します。
登録済オブジェクトに変更があるたびに、プロシージャhr.dcn_callbackを起動する必要があるとします。例13-1では、hr.dcn_callbackが変更通知を受け取るように指定するCHNF$_REG_INFOオブジェクトを作成します。オブジェクトを作成するには、DBMS_CHANGE_NOTIFICATIONパッケージに対するEXECUTE権限が必要であることに注意してください。
DECLARE v_cn_addr SYS.CHNF$_REG_INFO; BEGIN -- create the object v_cn_addr := SYS.CHNF$_REG_INFO ( 'hr.dcn_callback', -- name of PL/SQL callback procedure DBMS_CHANGE_NOTIFICATION.QOS_ROWIDS, -- include rowids of modified objects 0, -- registration persists until unregistered 0, -- notify on all types of DML 0 -- notify immediately (no transaction lag) ); -- ... register objects ... END; /
DBMS_CHANGE_NOTIFICATIONパッケージ内のサブプログラムを使用し、通知受信者を指定して問合せを登録します。このパッケージの詳細は、『Oracle Database PL/SQLパッケージ・プロシージャおよびタイプ・リファレンス』を参照してください。このパッケージの内容は、SYSとして接続して次のコマンドを実行するとSQL*Plusで表示できます。
DESC SYS.DBMS_CHANGE_NOTIFICATION
表13-2に、DBMS_CHANGE_NOTIFICATIONサブプログラムの概要を示します。
オブジェクト登録の例として、hr.employees表の1行が変更されるたびにクライアントが通知を必要とするとします。例13-2に、この表をhr.dcn_callbackプロシージャで登録する無名PL/SQLブロックを示します。このブロックを実行するには、CHANGE NOTIFICATION権限を付与されている必要があることに注意してください。
DECLARE v_cn_recip SYS.CHNF$_REG_INFO; v_regid NUMBER; v_employee_id hr.employees.manager_id%TYPE; BEGIN v_cn_recip := SYS.CHNF$_REG_INFO('hr.dcn_callback', DBMS_CHANGE_NOTIFICATION.QOS_ROWIDS, 0, 0, 0); -- begin the registration boundary v_regid := DBMS_CHANGE_NOTIFICATION.NEW_REG_START(v_cn_recip); SELECT employee_id INTO v_employee_id FROM hr.employees -- register the employees object WHERE ROWNUM < 2; -- write the query so that it returns a single row -- end the registration boundary DBMS_CHANGE_NOTIFICATION.REG_END; DBMS_OUTPUT.PUT_LINE('the registration id for this query is '||v_regid); END; /
例13-2では、プログラムはオブジェクト自体、つまりhr.employees表を登録します。フェッチにより複数行が戻されるため、エラー生成を回避するために、WHERE句により問合せは結果セット内の最初の従業員に制限されています。DBMS_CHANGE_NOTIFICATIONパッケージはオブジェクト自体を登録します。つまり、表に変更があると、登録済の問合せで戻される行が変更対象かどうかに関係なく、通知が生成されます。
hr.employeesの問合せの登録IDにhr.departments表の問合せを追加することになったとします。保存済SQL*Plus出力またはUSER_CHANGE_NOTIFICATION_REGSの問合せから登録IDを取得した後、例13-3のコードを使用し、reg_idの数値IDを置き換えて、このオブジェクトを追加できます。
DECLARE
v_department_id hr.departments.department_id%TYPE;
BEGIN
-- begin registration boundary
DBMS_CHANGE_NOTIFICATION.ENABLE_REG(reg_id);
SELECT department_id
INTO v_department_id
FROM hr.departments
WHERE ROWNUM < 2; -- register this query
-- end registration boundary
DBMS_CHANGE_NOTIFICATION.REG_END;
END;
/
次のデータ・ディクショナリ・ビューを問い合せて、データベース変更通知機能の登録済クライアントに関する情報を取得できます。
たとえば、クライアントの登録IDと通知を受信するオブジェクトのリストを取得できます。HRの登録IDと表名を表示するには、SQL*Plusから次のコマンドを実行できます。
connect hr/hr; SELECT regid, table_name FROM USER_CHANGE_NOTIFICATION_REGS;
トランザクションのコミット時に、Oracle Databaseでは登録済オブジェクトがトランザクション中に変更されたかどうかが判別されます。対象となったクライアントが検出されると、登録で指定されているコールバック・プロシージャが実行されます。
データベース変更の詳細は、データベースからCコールバックまたはPL/SQLプロシージャに引数として渡される記述子を介して公開されます。特に、Oracle Databaseでは、トップレベルの変更通知記述子であるCHNF$_DESCタイプのオブジェクトが渡されます。タイプ属性は、SYSとして接続して次のコマンドを実行するとSQL*Plusで表示できます。
DESC SYS.CHNF$_DESC
表13-3に、CHNF$_DESCの属性を示します。
| 属性 | 指定 |
|---|---|
|
|
登録時に戻された登録ID。 |
|
|
変更を行ったトランザクションのID。 |
|
|
変更があったオブジェクトが常駐するデータベースの名前。 |
|
|
通知をトリガーするデータベース・イベント。たとえば、属性には様々なデータベース・イベントに対応する次の定数を含めることができます。 |
|
|
変更された表の数。 |
|
|
|
CHNF$_DESCタイプには、CHNF$_TDESCタイプの表記述子の配列を保持する属性TABLE_DESC_ARRAYが含まれています。タイプ属性は、SYSとして接続して次のコマンドを実行するとSQL*Plusで表示できます。
DESC CHNF$_TDESC
表13-4に、CHNF$_TDESCの属性を示します。
| 属性 | 指定 |
|---|---|
|
|
変更があった表に対して実行された操作のタイプ。たとえば、属性には様々なデータベース操作に対応する次の定数を含めることができます。 |
|
|
変更があった表の名前。 |
|
|
変更があった行数。 |
|
|
|
登録時にROWIDオプションを選択した場合、CHNF$_TDESCタイプには変更された行のROWIDを含むCHNF$_RDESCタイプの配列が保持されます。注意: CHNF$_TDESCオブジェクトのopflagsフィールドにALL_ROWSが設定されていた場合、ROWID情報は使用できません。
表13-5に、CHNF$_RDESCの属性を示します。
| 属性 | 指定 |
|---|---|
|
|
変更があった表に対して実行された操作のタイプ。表13-4の |
|
|
変更された行の |
この使用例では、開発者として従業員データ(名前、所在地、電話番号など)を提供するWebアプリケーションを管理しているとします。このアプリケーションはOracle Application Serverで実行され、使用量が多く、バックエンド・データベースにあるhr.employees表およびhr.departments表の頻繁な問合せを処理します。この2つの表はあまり変更されないため、アプリケーションでは表の行をキャッシュすることでパフォーマンスを改善できます。キャッシュすると、バックエンド・データベースへのラウンドトリップのみでなく、サーバー側での実行待機時間も回避されます。
DBMS_CHANGE_NOTIFICATIONパッケージを使用すると、hr.employees表およびhr.departments表に基づく問合せを登録できます。データベース変更通知を構成する手順は、次のとおりです。
hr.employees表とhr.departments表に対する変更の通知に応答して中間層キャッシュを更新するように、中間層HTTPリスナーを実装します。
hr.employees表とhr.departments表を登録します。
手順1〜3を完了すると、手順2で定義したサーバー側PL/SQLプロシージャが、hr.employeesまたはhr.departmentsに対する変更に応答して実行されます。コールバック・プロシージャは、表の変更をWebアプリケーションに通知します。この通知に応答して、アプリケーションではバックエンド・データベースを問い合せてキャッシュをリフレッシュします。
この手順では、変更通知を処理するサーバー側ストアド・プロシージャを作成します。最初に、DBA権限を持つユーザーとしてデータベースに接続し、hrにEXECUTE権限を付与します。
GRANT EXECUTE ON DBMS_CHANGE_NOTIFICATION TO HR; GRANT CHANGE NOTIFICATION TO HR;
通知を受信するためにjob_queue_processesパラメータを有効化します。
ALTER SYSTEM SET "JOB_QUEUE_PROCESSES"=4;
受信した通知イベントのレコードを保持するデータベース表を作成できます。
connect hr/hr; Rem Create a table to record notification events CREATE table nfevents(regid number, event_type number); Rem Create a table to record changes to registered tables create table nftablechanges( regid number, table_name varchar2(100), table_operation number); Rem Create a table to record rowids of changed rows. create table nfrowchanges( regid number, table_name varchar2(100), row_id varchar2(2000));
次に、例13-4に示すようにプロシージャhr.chnf_callbackを作成します。
CREATE OR REPLACE PROCEDURE chnf_callback(ntfnds IN SYS.CHNF$_DESC) IS regid NUMBER; tbname VARCHAR2(60); event_type NUMBER; numtables NUMBER; operation_type NUMBER; numrows NUMBER; row_id VARCHAR2(2000); BEGIN regid := ntfnds.registration_id; numtables := ntfnds.numtables; event_type := ntfnds.event_type; insert into nfevents values(regid, event_type); IF (event_type = DBMS_CHANGE_NOTIFICATION.EVENT_OBJCHANGE) THEN FOR i IN 1..numtables LOOP tbname := ntfnds.table_desc_array(i).table_name; operation_type := ntfnds.table_desc_array(I). Opflags; insert into nftablechanges values(regid, tbname, operation_type); /* Send the table name and operation_type to client side listener using UTL_HTTP */ /* If interested in the rowids, obtain them as follows */ IF (bitand(operation_type, dbms_change_notification.ALL_ROWS) = 0) THEN numrows := ntfnds.table_desc_array(i).numrows; else numrows :=0; /* ROWID INFO NOT AVAILABLE */ END IF; /* The body of the loop is not executed when numrows is ZERO */ FOR j IN 1..numrows LOOP Row_id := ntfnds.table_desc_array(i).row_desc_array(j).row_id; insert into nfrowchanges values(regid, tbname, Row_id); /* optionally Send out row_ids to client side listener using UTL_HTTP */ END LOOP; END LOOP; END IF; commit; END; /
コールバック・プロシージャの作成後に、通知を受信する表に基づいて問合せを登録します。例13-5では、データベースによる通知の生成時に実行されるサーバー側PL/SQLプロシージャの名前としてhr.chnf_callbackを渡します。プロシージャを作成するには、CHANGE NOTIFICATION権限が必要であることに注意してください。
CREATE OR REPLACE PROCEDURE hr.table_reg IS v_regds SYS.CHNF$_REG_INFO; v_regid NUMBER; v_employee_id NUMBER; v_department_id NUMBER; BEGIN v_regds := SYS.CHNF$_REG_INFO ('hr.chnf_callback', DBMS_CHANGE_NOTIFICATION.QOS_ROWIDS, 0, 0, 0); v_regid := DBMS_CHANGE_NOTIFICATION.NEW_REG_START(v_regds); SELECT employee_id INTO v_employee_id FROM hr.employees -- register employees object WHERE ROWNUM < 2; -- return a single row to avoid multiple fetch error SELECT department_id INTO v_department_id FROM hr.departments -- register departments object WHERE ROWNUM < 2; -- return a single row to avoid multiple fetch error DBMS_CHANGE_NOTIFICATION.REG_END; END; / EXEC hr.table_reg
次の問合せを発行すると、新規に作成した登録を表示できます。
SQL> select regid, table_name from user_change_notification_regs; REGID TABLE_NAME ---------- ------------------------------------------------------------- 16 HR.EMPLOYEES 16 HR.DEPARTMENTS
前述のように登録を作成した後は、HR.EMPLOYEES表またはHR.DEPARTMENTS表に対するCOMMIT済変更に応答して、前述のサーバー側PL/SQLプロシージャchnf_callbackが実行されます。たとえば、employees表に対して次の更新が実行されるとします。
UPDATE employees SET salary=salary*1.05 WHERE employee_id=203; COMMIT;
通知が処理された後、nfevents、nftablechangesおよびnfrowchanges表に次のような行があることがわかります。
SQL> select * from nfevents; REGID EVENT_TYPE ---------- ---------- 20045 6 SQL> select * from nftablechanges; REGID TABLE_NAME TABLE_OPERATION ------------------------------------------- 20045 HR.EMPLOYEES 4 SQL> select * from nfrowchanges; REGID TABLE_NAME ROW_ID --------------------------------------------- 20045 HR.EMPLOYEES AAAKB/AABAAAJ8zAAF
変更通知に最適なパフォーマンスを得るためのガイドラインを次に示します。
登録済オブジェクトは少数であり、ほとんどが読取り専用で、この種のオブジェクトに対する変更はルールではなく例外です。オブジェクトの揮発性が非常に高いと、多数の無効化通知が送信されることになり、サーバー上の無効化キューに大量に格納される可能性があります。通知が頻繁で多数の場合は、通知の生成に伴うオーバーヘッドが原因でOLTPのスループットが低下する可能性があります。
また、同じ通知メッセージが複数の受信者宛に複製されないように、特定のオブジェクトについて重複登録の数を少なく(理想的には1に)しておくことをお薦めします。
登録を作成済であるのに通知を受信していないと思われる場合、または登録を作成できない場合は、次のリストをチェックしてください。
job_queue_processesパラメータが0(ゼロ)以外の値に設定されているかどうか。ハンドラを介してPL/SQL通知を受信するには、このパラメータを0(ゼロ)以外の値に設定する必要があります。
USER_CHANGE_NOTIFICATION_REGS またはDBA_CHANGE_NOTIFICATION_REGSビューから問い合せます。たとえば、現行のユーザーに関するすべての登録と登録済オブジェクトを表示するには、次のSELECT文を発行します。
SELECT regid, table_name FROM user_change_notification_regs;
JOBQプロセスのトレース・ファイルに記録されます。通常、トレース・ファイル名は<ORACLE_SID>_j*_<PID>.trcです。たとえば、ORACLE_SIDがdbs1で、JOBQプロセスのプロセスIDが12483の場合、トレース・ファイル名はdbs1_j000_12483.trcとなります。実行時エラーがある場合は、JOBQトレース・ファイルにレポートされます。たとえば、通知ハンドラにchnf_callback、登録IDに100を指定して登録が作成されている場合を考えてみます。ここで、chnf_callbackストアド・プロシージャがデータベースに定義されていないとします。この場合、JOBQトレース・ファイルには次の書式のメッセージが含まれます。
*************************************************************************** Runtime error during execution of PL/SQL cbk chnf_callback for reg CHNF100. Error in PLSQL notification of msgid: Queue : Consumer Name : PLSQL function :chnf_callback Exception Occured, Error msg: ORA-00604: 再帰SQLレベル2でエラーが発生しました。 ORA-06550: 行1、列7、 PLS-00201: 識別子CHNF_CALLBACKを宣言してください。 ORA-06550: 行1、列7、 PL/SQL: Statement ignored ****************************************************************************
HRの場合は、次のように非常に単純なバージョンの通知ハンドラを作成できます。
Rem create a table in the HR schema to hold a count of number of notifications received. Create table nfcount(cnt number); Insert into nfcount values(0); Commit; CREATE OR REPLACE PROCEDURE chnf_callback (ntfnds IN SYS.CHNF$_DESC) IS BEGIN update nfcount set cnt = cnt+1; commit; END; /
作成した単純なプロシージャにより、表のカウント列が増分されてコミットされます。通知が公開されているかどうかを確認するには、表nfcountから問い合せて、登録済オブジェクトが変更されてトランザクションがコミットされたときに、cnt列の値が実際に増えるかどうかを調べます。
|
![]() Copyright © 2006 Oracle Corporation. All Rights Reserved. |
|