4 Oracle Streams情報コンシューム
4.1 Oracle Streamsでの情報コンシュームの概要
Oracle Streamsでの情報のコンシュームとは、キューから情報を含むメッセージをデキューして、メッセージを処理または廃棄することです。コンシュームされる情報は、データベースの変更に関する説明の場合もあれば、その他の情報である場合もあります。デキューされたメッセージは、デキューされたデータベースで生成されていることもあれば、別のデータベースで生成されていることもあります。
この項の内容は次のとおりです。
4.1.1 Oracle Streamsで情報をコンシュームする方法
4.1.1.1 暗黙的コンシューム
暗黙的コンシュームでは、適用プロセスが取得LCR、永続LCRまたは永続ユーザー・メッセージを自動的にデキューします。キューはANYDATAキューであることが必要です。メッセージに論理変更レコード(LCR)が含まれる場合、適用プロセスでは、LCRを直接適用することも、ユーザー指定プロシージャをコールして処理することも可能です。メッセージにLCRが含まれない場合、適用プロセスではメッセージ・ハンドラと呼ばれるユーザー指定プロシージャを起動してメッセージを処理できます。
注意:
取得LCRは適用プロセスによってデキューされる必要があります。ただし、適用プロセスまたは適用プロセスによってコールされたユーザー・プロシージャが取得LCRを再エンキューする場合、LCRは永続LCRになり明示的にデキューできます。
4.1.1.2 明示的コンシューム
明示的コンシュームでは、メッセージは次のいずれかの方法でデキューされます。
-
メッセージ・クライアントで永続LCRまたは永続ユーザー・メッセージを明示的にデキューします。キューは
ANYDATA
キューである必要があります。メッセージ・クライアントは、アプリケーションによって起動された場合にメッセージをデキューします。メッセージ・クライアントがメッセージをデキューした後、アプリケーションがメッセージを処理します。 -
アプリケーションがメッセージを明示的に手動でデキューして処理します。アプリケーションは、タイプが永続LCR、永続ユーザー・メッセージ、バッファLCRおよびバッファ・ユーザー・メッセージであるメッセージをデキューできます。メッセージは、
ANYDATA
キューまたは型付きキューからデキューできます。
4.1.2 Oracle Streamsでコンシュームされる情報のタイプ
Oracle Streamsでコンシュームされる情報のタイプは次のとおりです。
4.1.2.1 取得LCR
4.1.2.2 永続LCR
永続LCRは、ANYDATA
キューの永続キュー部分にエンキューされた論理変更レコード(LCR)です。永続LCRは次のいずれかの方法でエンキューできます。
-
同期取得による暗黙的な取得およびエンキュー
-
アプリケーションによる明示的な作成およびエンキュー
-
適用プロセスによるデキュー、および同じ適用プロセスによる
DBMS_APPLY_ADM
パッケージ内のSET_ENQUEUE_DESTINATION
プロシージャを使用したエンキュー
永続LCRは、適用プロセス、メッセージ・クライアントまたはアプリケーションでデキューできます。
4.1.2.3 バッファLCR
バッファLCRは、アプリケーションによって明示的に作成され、ANYDATA
キューのバッファ・キュー部分にエンキューされた論理変更レコード(LCR)です。アプリケーションのみがバッファLCRをデキューできます。
関連項目:
4.1.2.4 永続ユーザー・メッセージ
永続ユーザー・メッセージは、永続キューにエンキューされたユーザー定義型のLCR以外のメッセージです。永続ユーザー・メッセージは次のいずれかの方法でエンキューできます。
-
アプリケーションによる明示的な作成およびエンキュー
-
適用プロセスによるデキュー、および同じ適用プロセスによる
DBMS_APPLY_ADM
パッケージ内のSET_ENQUEUE_DESTINATION
プロシージャを使用したエンキュー
適用プロセスおよびメッセージ・クライアントは、ANYDATAキューの永続ユーザー・メッセージのみをデキューできます。アプリケーションは、ANYDATA
キューまたは型付きキューの永続ユーザー・メッセージをデキューできます。
4.1.2.5 バッファ・ユーザー・メッセージ
バッファ・ユーザー・メッセージは、アプリケーションによって明示的に作成され、バッファ・キューにエンキューされたユーザー定義型のLCR以外のメッセージです。バッファ・ユーザー・メッセージは、ANYDATAキューまたは型付きキューのバッファ・キュー部分にエンキューできます。アプリケーションのみがバッファ・ユーザー・メッセージをデキューできます。
関連項目:
4.1.3 情報コンシューム・オプションのまとめ
表4-1に、Oracle Streamsで使用可能な情報コンシューム・オプションのまとめを示します。
表4-1 Oracle Streamsでの情報コンシューム・オプション
コンシュームのタイプ | メッセージのデキュー | メッセージのタイプ | 使用ケース |
---|---|---|---|
有効にすると自動的に継続して行われる |
取得LCR 永続LCR 永続ユーザー・メッセージ |
取得LCRをデキューして処理する場合。 永続LCRまたは永続ユーザー・メッセージを、ANYDATAキューの永続キュー部分から自動的に継続してデキューする場合。 データベースを変更するためにデータベース・オブジェクトに直接適用する必要があるLCRをデキューする場合。 メッセージをデキューし、適用ハンドラを使用して処理する場合。 |
|
アプリケーションから起動されたときに行われる |
永続LCR 永続ユーザー・メッセージ |
単純な方法を使用して、 デキューの後でメッセージをアプリケーションに処理のために送信する場合。 |
|
アプリケーションのロジックに基づいて手動で行われる |
永続LCR バッファLCR 永続ユーザー・メッセージ バッファ・ユーザー・メッセージ |
アプリケーションで永続LCRまたはバッファLCRを手動で アプリケーションで永続ユーザー・メッセージまたはバッファ・ユーザー・メッセージを手動で |
注意:
1つのデータベースで、この表の情報コンシューム・オプションを任意に組み合せて使用することができます。
関連項目:
-
メッセージのエンキューの詳細は、『Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド』を参照
-
LCRの管理の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
4.2 適用プロセスによる暗黙的コンシューム
この項では、Oracle Streamsの適用プロセスに関連する概念について説明します。
この項の内容は次のとおりです。
4.2.1 適用プロセスの概要
適用プロセスとは、メッセージを特定のキューからデキューし、各メッセージを直接適用したり、廃棄したり、適用ハンドラにパラメータとして渡したり、または再リクエストするための、オプションのOracleバックグラウンド・プロセスです。これらのメッセージは、論理変更レコード(LCR)またはユーザー・メッセージです。
注意:
適用プロセスでデキューできるのは、ANYDATAキューのメッセージのみです。型付きキューからはデキューできません。
4.2.2 適用プロセスのルール
適用プロセスは、ユーザーが定義するルールに基づいてメッセージを適用します。LCRの場合は、各ルールでTRUE
と評価するデータベース・オブジェクトと変更の種類を指定します。ユーザー・メッセージの場合は、特定のタイプのメッセージに対する適用プロセスの動作を制御するルールを作成できます。これらのルールは、適用プロセスのポジティブ・ルール・セットまたはネガティブ・ルール・セットに指定します。
メッセージに対してルールがTRUE
と評価され、そのルールが適用プロセスのポジティブ・ルール・セットに含まれる場合、適用プロセスはメッセージをデキューして処理します。メッセージに対してルールがTRUE
と評価され、そのルールが適用プロセスのネガティブ・ルール・セットに含まれる場合、適用プロセスはメッセージを廃棄します。適用プロセスにポジティブ・ルール・セットとネガティブ・ルール・セットの両方がある場合、ネガティブ・ルール・セットが常に最初に評価されます。
LCRの適用プロセスのルールは次のレベルで指定できます。
-
表ルールは、特定の表に対するDML変更による行変更またはDDL変更を適用または廃棄します。サブセット・ルールは、特定の表に対する行変更のサブセットを含む表ルールです。
-
スキーマ・ルールは、特定のスキーマのデータベース・オブジェクトに対するDML変更による行変更またはDDL変更を適用または廃棄します。
-
グローバル・ルールは、適用プロセスに関連付けられているキュー内のDML変更によるすべての行変更またはすべてのDDL変更を適用または廃棄します。
関連項目:
4.2.3 適用プロセスで処理できるメッセージのタイプ
適用プロセスでデキューできるメッセージのタイプを次に示します。
-
取得LCR: 取得プロセスによって暗黙的に取得され、ANYDATAキューのバッファ・キュー部分にエンキューされた論理変更レコード(LCR)。状況によっては、最適化を行って、取得プロセスでLCRを適用プロセスにより効率的に送信することもできます。このような最適化は、取得と適用の複合と呼ばれます。
-
永続LCR: 同期取得によって暗黙的に取得されたLCR、アプリケーションによって永続的に作成およびエンキューされたLCR、または適用プロセスによってエンキューされたLCR。永続LCRは
ANYDATA
キューの永続キュー部分にエンキューされます。 -
永続ユーザー・メッセージ: アプリケーションまたは適用プロセスによって明示的にエンキューされたユーザー定義型のLCR以外のメッセージ。永続ユーザー・メッセージは、
ANYDATA
キューの永続キュー部分にエンキューされます。また、ユーザー・メッセージはANYDATA
キューまたは型付きキューにエンキューできますが、適用プロセスでデキューできるのはANYDATA
キューのユーザー・メッセージのみです。
1つの適用プロセスで、1つのキューのバッファ・キュー部分と永続キュー部分の両方からデキューを行うことはできません。バッファ・キューと永続キューの両方のメッセージを適用プロセスで処理する必要がある場合は、宛先データベースにメッセージを処理するための2つ以上の適用プロセスが必要です。
関連項目:
-
適用プロセスを作成する方法の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
4.2.4 適用プロセスのメッセージ処理オプション
適用プロセスは、メッセージを直接適用するか、メッセージを適用ハンドラに送信して処理します。メッセージ処理のオプションは、適用プロセスで受信したメッセージが行論理変更レコード(行LCR)、DDL論理変更レコード(DDL LCR)、ユーザー・メッセージのいずれであるかによって異なります。
図4-1に、適用プロセスのメッセージ処理オプションおよび様々なタイプのメッセージに使用できるオプションを示します。
デフォルトでは、適用プロセスはLCRを直接適用します。適用プロセスは、LCR内の変更を該当のデータベース・オブジェクトに対して実行します。LCR内の変更が正常に適用されなかった場合、つまり、競合または適用エラーが発生した場合は、競合ハンドラまたはエラー・ハンドラと呼ばれるユーザー指定プロシージャを使用してエラーの解決が試行されます。
競合ハンドラが競合を解消できる場合は、競合ハンドラがLCRを適用するか、LCR内の変更を廃棄します。エラー・ハンドラがエラーを解決できる場合は、エラー・ハンドラが必要に応じてLCRを適用します。エラー・ハンドラは、適用前にLCRを変更することでエラーを解決できる場合があります。競合ハンドラまたはエラー・ハンドラがエラーを解決できない場合、適用プロセスは、トランザクションとトランザクションに関連付けられたすべてのLCRをエラー・キューに入れます。
LCRを直接適用するかわりに、適用ハンドラを使用し、カスタマイズした方法でLCRを処理することもできます。適用ハンドラを使用した場合、適用プロセスはメッセージをSQL文のコレクションに渡すか、またはユーザー定義のPL/SQLプロシージャに渡します。適用ハンドラにより、メッセージをカスタムな方法で処理することができます。
適用プロセスは、ユーザー・メッセージを直接適用することはできません。ユーザー・メッセージをデキューする適用プロセスは、そのユーザー・メッセージを処理するためのメッセージ・ハンドラを持つ必要があります。
適用ハンドラにはいくつかのタイプがあります。この項では、適用ハンドラを次のカテゴリに分けて説明します。
表4-2 適用ハンドラの特性
カテゴリ | 説明 |
---|---|
メカニズム |
適用ハンドラがメッセージの処理に使用する手段のことです。適用ハンドラに使用されるメカニズムは、SQL文、またはユーザー定義のPL/SQLプロシージャです。 |
メッセージのタイプ |
適用ハンドラによって処理されるメッセージのタイプです。メッセージ・タイプには、行論理変更レコード(行LCR)、DDL論理変更レコード(DDL LCR)、永続ユーザー・メッセージ、およびトランザクション制御ディレクティブがあります。 |
メッセージ・クリエータ |
適用ハンドラによって処理されるメッセージを作成するコンポーネントです。メッセージ・クリエータは、取得プロセス、同期取得、またはアプリケーションのいずれかになります。 |
有効範囲 |
適用ハンドラに設定されたレベルのことです。有効範囲は、1つの表に対する1つの操作か、またはすべてのデータベースに対するすべての操作のいずれかになります。 |
各適用プロセスへの割当て数 |
各適用プロセスに対して、そのタイプの適用ハンドラがいくつ割り当てられるかを示す数です。割当て数は1つまたは複数のいずれかになります。 |
適用ハンドラの各タイプについては、次の各項で説明しています。
注意:
適用プロセスはLCR以外のメッセージを直接適用することはできません。適用プロセスでデキューしたユーザー・メッセージは、メッセージ・ハンドラで処理する必要があります。
4.2.4.1 DMLハンドラ
DMLハンドラは、適用プロセスによってデキューされた行論理変更レコード(行LCR)を処理します。DMLハンドラには2つのタイプがあります。文DMLハンドラとプロシージャDMLハンドラです。文DMLハンドラは、SQL文のコレクションを使用して行LCRを処理します。一方プロシージャDMLハンドラは、PL/SQLプロシージャを使用して行LCRを処理します。
DMLハンドラとエラー・ハンドラについては、次の各項で詳しく説明しています。
4.2.4.1.1 文DMLハンドラ
文DMLハンドラの特性は次のとおりです。
-
メカニズム: SQL文のコレクション
-
メッセージのタイプ: 行LCR
-
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション
-
有効範囲: 1つの表に対する1つの操作
-
各適用プロセスへの割当て数: 複数(同じ表に対する同じ操作について複数指定可能)
文DMLハンドラに含まれる各SQL文には、それぞれ固有の実行順序番号があります。文DMLハンドラが呼び出されると、文は実行順序番号の小さいものから大きいものへと進める順序で実行されます。実行順序番号は、正の数、負の数、または小数で指定できます。
文DMLハンドラは、適用プロセスに関連付けられている表ごとに個別に設定できます。処理できる操作(行LCR内の操作)は次のとおりです。
-
INSERT
-
UPDATE
-
DELETE
文DMLハンドラは、特定の表に対する特定の操作に対応し、その操作を実行する行LCRが適用プロセスによってデキューされたときに呼び出されます。そのため、たとえばhr.employees
表でINSERT
操作を処理するための文DMLハンドラを1つ設定し、それとは別に、UPDATE
操作を処理するための文DMLハンドラをもう1つ設定することなどが可能です。また、hr.employees
表にあるこれら各タイプの操作に、同じ文DMLハンドラを使用することもできます。
同じ表に対する同じ操作について、複数の文DMLハンドラを指定することもできます。その場合、それらの文DMLハンドラは任意の順序で実行できます。なお、それぞれの文DMLハンドラは、適用プロセスによってデキューされた、元の行LCRのコピーを受け取ります。
文DMLハンドラ内のSQL文では、行LCRに含まれる次のタイプの操作を使用することができます。
-
INSERT
-
UPDATE
-
DELETE
-
MERGE
たとえば、文DMLハンドラ内のSQL文で、hr.employees
表を更新する行LCRを処理し、その文に、別の表への行挿入を行うためのINSERT
操作を含めることなどもできます。
文DMLハンドラでは、行LCR上の有効なDML文を実行することはできますが、行LCR内の列値を修正することはできません。ただし、文DMLハンドラでSQLを使用し、行を挿入したり、行LCRの列値とは異なる列値で行を更新できます。なお、文DMLハンドラによってコミットやロールバックが実行されることはありません。
文DMLハンドラ内で行LCRを実行するには、その行LCRのEXECUTE
メンバー・プロシージャを呼び出します。EXECUTE
メンバー・プロシージャを実行する文は、文DMLハンドラの何番目の実行順序番号に配置することもできます。行LCRは、文DMLハンドラ内のその他のSQL文実行以外に、行LCRの変更を特定の表に適用する場合以外は実行する必要はありません。
文DMLハンドラに文を追加するには、DBMS_STREAMS_HANDLER_ADM
パッケージ内のADD_STMT_TO_HANDLER
プロシージャを使用します。適用プロセスに文DMLハンドラを追加するには、DBMS_APPLY_ADM
パッケージ内のADD_STMT_HANDLER
プロシージャを使用します。文DMLハンドラは、特定の適用プロセスに対して追加することもできますし、データベース内のすべての適用プロセスによって使用される、汎用の文DMLハンドラとして追加することもできます。表の操作に対する文DMLハンドラが特定の適用プロセスによって使用され、かつ別の文DMLハンドラが同じ表の同じ操作に対する汎用ハンドラとして存在する場合、適用プロセスでその表への操作を含む行LCRがデキューされたときには、両方のハンドラが呼び出されます。各文DMLハンドラによって元の行LCRが受け取られ、文DMLハンドラは任意の順序で実行できます。
文DMLハンドラは、表に加えられた変更を記録する目的で使用されることもよくあります。また、文DMLハンドラでは、列値を修正しないで変更を実行することもできます。たとえば、文DMLハンドラを使用して、特定の列のデータ型を変更することなども可能です。
注意:
関連項目:
-
「行LCR」
-
変更ハンドラの詳細は、「Oracle Streamsを使用した表の変更の記録」を参照
-
LCRタイプの
EXECUTE
メンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
4.2.4.1.2 プロシージャDMLハンドラ
プロシージャDMLハンドラの特性は次のとおりです。
-
メカニズム: ユーザー定義のPL/SQLプロシージャ
-
メッセージのタイプ: 行LCR
-
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション
-
有効範囲: 1つの表に対する1つの操作
-
各適用プロセスへの割当て数: 複数(ただし、同じ表に対する同じ操作については1つのみ指定可能)
プロシージャDMLハンドラは、適用プロセスに関連付けられている表ごとに個別に設定できます。処理できる操作(行LCR内の操作)は次のとおりです。
-
INSERT
-
UPDATE
-
DELETE
-
LOB_UPDATE
プロシージャDMLハンドラは、特定の表に対する特定の操作に対応し、その操作を実行する行LCRが適用プロセスによってデキューされたときに呼び出されます。そのため、たとえばhr.employees
表でINSERT
操作を処理するためのプロシージャDMLハンドラを1つ設定し、それとは別に、UPDATE
操作を処理するためのプロシージャDMLハンドラをもう1つ設定することなどが可能です。また、hr.employees
表にあるこれら各タイプの操作に、同じプロシージャDMLハンドラを使用することもできます。
PL/SQLプロシージャでは、行LCRの処理を自由にカスタマイズして実行できます。たとえば、ソース・データベースの特定の表に対して挿入が行われるたびに、宛先データベースの複数の表に対して挿入が実行されるようにする場合は、その表に対するINSERT
操作を処理するためのPL/SQLプロシージャをユーザー定義で作成すれば解決できます。文DMLハンドラと違い、プロシージャDMLハンドラでは行LCR内の列値を修正することができます。
プロシージャDMLハンドラによってコミットやロールバックが実行されることはありません。ただし、ユーザー定義のPL/SQLプロシージャによって設定された名前付きセーブポイントがある場合は例外です。DMLハンドラ内で行LCRを実行するには、行LCRのEXECUTE
メンバー・プロシージャを呼び出します。なお、プロシージャDMLハンドラでは、処理中に発生したエラーをすべて処理する必要があります。
プロシージャDMLハンドラを設定するには、DBMS_APPLY_ADM
パッケージ内のSET_DML_HANDLER
プロシージャを使用します。プロシージャDMLハンドラは、特定の適用プロセスに対して設定することもできますし、データベース内のすべての適用プロセスによって使用される、汎用のハンドラとして設定することもできます。なお、ある表への操作を処理するプロシージャDMLハンドラが特定の適用プロセス専用に設定されていて、それとは別に、それと同じ表への同じ操作を処理する汎用のプロシージャDMLハンドラも存在する場合は、専用のハンドラが汎用のハンドラよりも優先されます。
プロシージャDMLハンドラは通常、行LCRをカスタムで処理するために、Oracle Streamsレプリケーション環境内で使用されますが、レプリケーション環境以外で使用することもできます。たとえば、データベース・オブジェクトに加えられた変更を、レプリケートせずに記録する場合にも使用できます。
注意:
SET_DML_HANDLER
プロシージャを実行するときは、ハンドラを使用する対象のオブジェクトを指定します。このオブジェクトはプロシージャの実行時に宛先データベースに存在する必要はありません。
関連項目:
-
「行LCR」
-
LCRタイプの
EXECUTE
メンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
4.2.4.2 エラー・ハンドラ
エラー・ハンドラの特性は次のとおりです。
-
メカニズム: ユーザー定義のPL/SQLプロシージャ
-
メッセージのタイプ: 行LCR
-
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション
-
有効範囲: 1つの表に対する1つの操作
-
各適用プロセスへの割当て数: 複数(ただし、同じ表に対する同じ操作については1つのみ指定可能)
エラー・ハンドラは、プロシージャDMLハンドラに似ています。ただしエラー・ハンドラは、特定の表に対して特定の操作を行うための行LCRを適用プロセスが適用する際、適用エラーが発生した場合にのみ呼び出されます。
エラー・ハンドラは基本的にプロシージャDMLハンドラと同じ方法で作成しますが、SET_DML_HANDLER
プロシージャを実行する際、error_handler
パラメータをTRUE
に設定するという点が異なります。
エラー・ハンドラは、同じ表への同じ操作を行うプロシージャDMLハンドラとは共存できません。ただし、同じ表に同じ操作を行う場合でも、文DMLハンドラエラー・ハンドラとは共存できます。
注意:
文DMLハンドラは、エラー・ハンドラとしては使用できません。
関連項目:
4.2.4.3 DDLハンドラ
DDLハンドラの特性は次のとおりです。
-
メカニズム: ユーザー定義のPL/SQLプロシージャ
-
メッセージのタイプ: DDL LCR
-
メッセージ・クリエータ: 取得プロセス、またはアプリケーション
-
有効範囲: 適用プロセスによってデキューされたすべてのDDL LCR
-
各適用プロセスへの割当て数: 1つ
ユーザー定義のPL/SQLプロシージャでは、DDL LCRの処理を自由にカスタマイズして実行できます。たとえば、DDL変更を適用の前に記録する場合、DDL操作の処理に使用するプロシージャを独自に作成することでこのことを実現できます。
DDLハンドラ内でDDL LCRを実行するには、DDL LCRのEXECUTE
メンバー・プロシージャを起動します。DDLハンドラを特定の適用プロセスに関連付けるには、DBMS_APPLY_ADM
パッケージのCREATE_APPLY
プロシージャまたはALTER_APPLY
プロシージャのddl_handler
パラメータを使用します。
DDLハンドラは通常、DDL LCRをカスタムで処理するために、Oracle Streamsレプリケーション環境内で使用されますが、レプリケーション環境以外で使用することもできます。たとえば、データベース・オブジェクトに加えられた変更を、レプリケートせずに記録する場合にも使用できます。
関連項目:
-
「DDL LCR」
-
LCRタイプの
EXECUTE
メンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
DDLハンドラの詳細は、「DDLハンドラの管理」を参照
4.2.4.4 メッセージ・ハンドラ
メッセージ・ハンドラの特性は次のとおりです。
-
メカニズム: ユーザー定義のPL/SQLプロシージャ
-
メッセージのタイプ: 永続ユーザー・メッセージ(非LCR)
-
メッセージ・クリエータ: アプリケーション
-
有効範囲: 適用プロセスによってデキューされたすべてのユーザー・メッセージ
-
各適用プロセスへの割当て数: 1つ
メッセージ・ハンドラは、1つ以上のリモート・データベースの更新または他のリモート・アクションを実行する必要のあるアプリケーションを含む環境においてメリットがあります。このようなアプリケーションが永続ユーザー・メッセージをローカル・データベースのキューにエンキューすると、Oracle Streamsが各永続ユーザー・メッセージを宛先データベースの適切なキューに伝播できます。複数の宛先がある場合、Oracle Streamsはこれらのメッセージを自動的に各宛先に伝播して処理するためのインフラストラクチャを提供します。宛先が1つしかない場合も、Oracle Streamsはソース・データベースのアプリケーションと宛先データベースのアプリケーションの間にレイヤーを提供します。これによって、リモート・データベースのアプリケーションが使用不可能になった場合も、ソース・データベースのアプリケーションはそのまま正常に動作できます。
たとえば、メッセージ・ハンドラは、永続ユーザー・メッセージを電子メール・メッセージに変換できます。この場合、永続ユーザー・メッセージには、from
、to
、subject
、text_of_message
など、電子メール・メッセージで使用される属性を含めることができます。メッセージを電子メール・メッセージに変換した後、メッセージ・ハンドラがそのメッセージを電子メール・ゲートウェイを介して送信できます。
適用プロセスにメッセージ・ハンドラを指定するには、DBMS_APPLY_ADM
パッケージのCREATE_APPLY
プロシージャまたはALTER_APPLY
プロシージャのmessage_handler
パラメータを使用します。Oracle Streams適用プロセスでは、常に、LCR以外のメッセージはキューのその他のメッセージに依存しないとみなされます。永続ユーザー・メッセージを適用する適用プロセスの並列性が1
より大きい場合、これらのメッセージはメッセージ・ハンドラによって任意の順序でデキューされます。このため、ご使用の環境でメッセージ間に依存性がある場合は、適用プロセスの並列性を1
に設定することをお薦めします。
関連項目:
4.2.4.5 プリコミット・ハンドラ
プリコミット・ハンドラの特性は次のとおりです。
-
メカニズム: ユーザー定義のPL/SQLプロシージャ
-
メッセージのタイプ: 行LCRまたは永続ユーザー・メッセージを含むトランザクションのコミット・ディレクティブ
-
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション
-
有効範囲: 適用プロセスによってデキューされたコミット・ディレクティブに付属するすべての行LCR
-
各適用プロセスへの割当て数: 1つ
プリコミット・ハンドラを使用して、取得LCRのコミット・ディレクティブ、および永続LCRと永続ユーザー・メッセージのトランザクション境界を監査できます。コミット・ディレクティブは、COMMIT
を含むトランザクション制御ディレクティブです。プリコミット・ハンドラは、トランザクションのコミット情報を受信し、カスタマイズした方法でコミット情報を処理できるユーザー定義のPL/SQLプロシージャです。プリコミット・ハンドラは、文DMLハンドラ、プロシージャDMLハンドラ、またはメッセージ・ハンドラと併用できます。
たとえば、プリコミット・ハンドラで1トランザクション分のデータをキャッシュすることで、パフォーマンスが改善される場合があります。このデータには、カーソル、一時LOB、メッセージのデータなどが含まれます。プリコミット・ハンドラは、トランザクションが完了すると、ハンドラでキャッシュしたオブジェクトを解放または実行できます。
プリコミット・ハンドラは、適用プロセスがトランザクションをコミットするときに実行されます。適用プロセスのcommit_serialization
パラメータを使用すると、適用プロセスのコミット順序を制御できます。
次に、コミット・ディレクティブとトランザクション境界について説明します。
-
取得LCRのコミット・ディレクティブ: 取得プロセスの使用中にユーザーがトランザクションをコミットすると、取得プロセスによって取得された行LCRがトランザクションに含まれている場合、取得プロセスによってトランザクションの内部コミット・ディレクティブが取得されます。また、取得プロセスによって、トランザクション内の各取得LCRにトランザクション識別子も記録されます。
コミット・ディレクティブは、エンキューされた後、トランザクション内のLCRとともに宛先キューに伝播できます。プリコミット・ハンドラによって、これらの内部コミット・ディレクティブのコミットSCNが適用プロセスのキューに受信されます。その後、それらのコミット・ディレクティブが適用プロセスによって処理されます。
-
同期取得によってエンキューされた永続LCRのトランザクション境界: 同期取得の使用中にユーザーがトランザクションをコミットすると、同期取得によってエンキューされた永続LCRはメッセージ・グループに編成されます。同期取得は、トランザクション内の各永続LCRにトランザクション識別子を記録します。
同期取得によって永続LCRがエンキューされた後、メッセージ・グループの永続LCRを他のキューに伝播できます。適用プロセスがこれらの永続LCRを処理するように構成されている場合は、メッセージ・グループのすべての永続LCRに対して1つのコミットSCNが生成されます。個々の適用プロセスで生成されるコミットSCNの値は、ソース・トランザクションまたは他の適用プロセスで生成される値とは関係ありません。そのような適用プロセスに対して構成されているプリコミット・ハンドラが、適用プロセスによって提供されるコミットSCNを受信します。
-
アプリケーションによってエンキューされたメッセージのトランザクション境界: アプリケーションでは、永続LCR、永続ユーザー・メッセージおよびその他のタイプのメッセージをエンキューできます。これらのエンキュー操作を行っているユーザーが、
COMMIT
文を発行してトランザクションを終了すると、エンキューされた永続LCRおよび永続ユーザー・メッセージは、メッセージ・グループに編成されます。アプリケーションによってエンキューされたメッセージがメッセージ・グループに分類されると、メッセージ・グループのメッセージを他のキューに伝播できます。適用プロセスがこれらのメッセージを処理するように構成されている場合は、メッセージ・グループのすべてのメッセージに対して1つのトランザクション識別子とコミットSCNを生成します。個々の適用プロセスで生成されるトランザクション識別子とコミットSCNの値は、ソース・トランザクションまたは他の適用プロセスで生成される値とは関係ありません。そのような適用プロセスに対して構成されているプリコミット・ハンドラが、適用プロセスによって提供されるコミットSCNを受信します。
関連項目:
-
適用プロセス・パラメータの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
4.2.4.6 適用ハンドラに関する考慮事項
適用ハンドラを使用する際には、次の点を考慮する必要があります。
-
文DMLハンドラとプロシージャDMLハンドラは、どちらも行LCRを処理します。違いとしては、プロシージャDMLハンドラではPL/SQLの処理が必要なのに対し、文DMLハンドラでは必要ありません。そのため、通常は文DMLハンドラの方がプロシージャDMLハンドラよりもよいパフォーマンスで動作します。また、通常は構成作業も文DMLハンドラの方が簡単です。ただし、プロシージャDMLハンドラには、文DMLハンドラで処理できない操作を実行できるという利点があります(プログラム・フローの制御やエラーのトラップなど)。また、プロシージャDMLハンドラでは、行LCR内の列値を修正することもできます(文DMLハンドラではできない)。
-
文DMLハンドラ、プロシージャDMLハンドラ、エラー・ハンドラ、DDLハンドラおよびメッセージ・ハンドラは、LCRの
EXECUTE
メンバー・プロシージャをコールしてLCRを実行できます。 -
適用されたDDL LCRはすべて自動的にコミットします。したがって、DDLハンドラがDDL LCRの
EXECUTE
メンバー・プロシージャをコールすると、自動的にコミットが実行されます。 -
PL/SQLプロシージャを使用する適用ハンドラは、Oracle Streamsセッション・タグを設定できます。文DMLハンドラは、Oracle Streamsセッション・タグを設定できません。
-
ユーザー定義のPL/SQLプロシージャを使用する適用ハンドラは、PL/SQLプロシージャでパブリッシュ(またはラップ)されたJavaストアド・プロシージャをコールできます。文DMLハンドラは、Javaストアド・プロシージャをコールできません。
-
適用プロセスが、存在しない適用ハンドラまたは無効な適用ハンドラを起動しようとすると、その適用プロセスは強制終了されます。
-
PL/SQLプロシージャを使用した適用ハンドラでOracle提供パッケージのプロシージャまたはファンクションを呼び出す場合、適用ハンドラを実行するユーザーにはそのパッケージに対する直接の
EXECUTE
権限が必要です。ロールを介してこの権限を付与するのみでは不十分です。DBMS_STREAMS_AUTH.GRANT_ADMIN_PRIVILEGE
プロシージャを実行すると、すべてのOracle Streamsパッケージ、およびOracle Streamsに関連する他の権限に対するEXECUTE
権限が付与されます。一方、文DMLハンドラではプロシージャやファンクションを呼び出すことはできません。
関連項目:
-
LCRタイプの
EXECUTE
メンバー・プロシージャの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
Oracle Streamsタグの詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
4.2.4.7 メッセージ処理オプションのまとめ
前述した1つ以上の適用ハンドラを使用する場合に有効なメッセージ処理オプションを、この項の表に示します。行LCRとDDL LCRは適用プロセスで直接適用できるため、適用ハンドラはオプションです。ただし、永続ユーザー・メッセージを処理するにはメッセージ・ハンドラが必須です。また、適用プロセスがメッセージをデキューするのは、そのメッセージが適用プロセスのルール・セットを満たしている場合のみです。通常、メッセージが適用プロセスのルール・セットを満たすのは、メッセージについてネガティブ・ルール・セットのどのルールもTRUE
と評価されず、ポジティブ・ルール・セットの少なくとも1つのルールがTRUE
と評価された場合です。
表4-3は、適用プロセスのメッセージ処理オプションをまとめたものです。
表4-3 メッセージ処理オプションのまとめ
メッセージ処理オプション | メカニズム | メッセージのタイプ | メッセージ・クリエータ | 適用プロセスのデフォルト動作 | ハンドラの有効範囲 | 各適用プロセスへの割当て数 |
---|---|---|---|---|---|---|
メッセージの直接適用 |
該当なし |
行LCRまたはDDL LCR |
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション |
DMLまたはDDLを実行 |
該当なし |
該当なし |
文DMLハンドラ |
SQL文 |
行LCR |
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション |
DMLを実行 |
1つの表に対する1つの操作 |
複数(ただし、同じ表に対する同じ操作については複数指定可能) |
プロシージャDMLハンドラまたはエラー・ハンドラ |
ユーザー定義のPL/SQLプロシージャ |
行LCR |
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション |
DMLを実行 |
1つの表に対する1つの操作 |
複数(ただし、同じ表に対する同じ操作については1つのみ指定可能) |
DDLハンドラ |
ユーザー定義のPL/SQLプロシージャ |
DDL LCR |
取得プロセス、またはアプリケーション |
DDLを実行 |
適用プロセス全体 |
1つ |
メッセージ・ハンドラ |
ユーザー定義のPL/SQLプロシージャ |
永続ユーザー・メッセージ |
アプリケーション |
エラー・トランザクションを作成(メッセージ・ハンドラが存在しない場合) |
適用プロセス全体 |
1つ |
プリコミット・ハンドラ |
ユーザー定義のPL/SQLプロシージャ |
行LCRまたはユーザー・メッセージを含むトランザクションのコミット・ディレクティブ |
メッセージ・クリエータ: 取得プロセス、同期取得、またはアプリケーション |
トランザクションをコミット |
適用プロセス全体 |
1つ |
ここで説明したメッセージ処理オプションに加えて、DBMS_APPLY_ADM
パッケージのSET_ENQUEUE_DESTINATION
プロシージャを使用すると、指定した宛先キューの永続キュー部分にメッセージをエンキューするように適用プロセスに指示できます。また、メッセージの実行を制御するには、DBMS_APPLY_ADM
パッケージのSET_EXECUTE
プロシージャを使用する方法もあります。
4.2.5 適用プロセスによって適用されるメッセージのソース
適用プロセスで処理できる様々なメッセージのタイプに対応するソース・データベースを次に示します。
-
同期取得によって取得された永続LCRの場合、ソース・データベースは、行LCRを取得した同期取得が構成されているデータベースです。
-
アプリケーションによって作成およびエンキューされた永続LCRの場合、ソース・データベースはメッセージが最初にエンキューされたデータベースです。
-
ユーザー・メッセージの場合、ソース・データベースは、メッセージが最初にエンキューされたデータベースです。
1つの適用プロセスでは、複数のデータベースで発生したユーザー・メッセージを適用できます。一方、1つの適用プロセスでは、1つのソース・データベースのみから取得された取得LCRを適用できます。同様に、1つの適用プロセスでは、1つのソース・データベースのみから同期取得によって取得された永続LCRを適用できます。このようなLCRの適用には、依存関係、有効なトランザクション順序指定、およびソース・データベースでのトランザクション境界の理解が必要です。
複数のデータベースの取得LCRを1つの宛先キューに送信できます。同期取得により取得された永続LCRについても同様です。ただし、1つのキューに複数のソース・データベースのLCRが含まれる場合、それらのLCRを取得する複数の適用プロセスが必要です。ルールを使用して各適用プロセスが1つのソース・データベースからのメッセージを受信するように構成してください。各ソース・データベースのメッセージに対して別のANYDATA
キューを使用することをお薦めします。
また、各適用プロセスで適用できるのは、1つの取得プロセスからの取得LCRのみです。ソース・データベース上で複数の取得プロセスが実行されていて、複数の取得プロセスからのLCRが宛先データベースで適用される場合は、各取得プロセスからの変更を適用するために1つの適用プロセスが必要です。このような環境では、取得プロセス、伝播または適用プロセスで使用される各ANYDATA
キューで、特定のソース・データベースの最大1つの取得プロセスからの取得LCRを格納することをお薦めします。キューが複数の取得プロセスからのLCRを含むことができるのは、各取得プロセスが別のソース・データベースで発生した変更を取得している場合です。
同じソース・データベースの複数の同期取得で取得された永続LCRにも同じ制約が適用されます。これらのLCRは別のANYDATA
キューに格納し、個別の適用プロセスを使用して各同期取得のLCRを適用します。
注意:
取得LCRはキューのバッファ・キュー部分に格納されますが、永続LCRはキューの永続キュー部分に格納されます。このため、1つの適用プロセスで取得LCRと永続LCRの両方を適用することはできません。
関連項目:
4.2.6 適用されるデータ型
DML変更で生成される行LCRを表に適用するとき、適用プロセスは、次のデータ型の列に変更を適用します。
-
VARCHAR2
-
NVARCHAR2
-
NUMBER
-
FLOAT
-
LONG
-
DATE
-
BINARY_FLOAT
-
BINARY_DOUBLE
-
TIMESTAMP
-
TIME
WITH
TIME
ZONE
-
TIMESTAMP
WITH
LOCAL
TIME
ZONE
-
INTERVAL
YEAR
TO
MONTH
-
INTERVAL
DAY
TO
SECOND
-
RAW
-
LONG
RAW
-
CHAR
-
NCHAR
-
BASICFILE
またはSECUREFILE
記憶域を持つCLOB
-
BASICFILE
またはSECUREFILE
記憶域を持つNCLOB
-
BASICFILE
またはSECUREFILE
記憶域を持つBLOB
-
UROWID
-
CLOB
、オブジェクト・リレーショナルまたはバイナリXMLとして格納されているXMLType
注意:
-
Oracle Streams取得プロセスは、
CLOB
として格納されているXMLType
列への変更しか取得できません。ただし、適用プロセスは、このような取得LCRを、CLOB
、オブジェクト・リレーショナルまたはバイナリXMLとして格納されているXMLType
列に適用することはできます。 -
適用プロセスでは、Oracle Database 12cで導入された拡張データ型はサポートしていません。
-
CLOB
として格納されたXMLType
は、このリリースでは非推奨です。
関連項目:
4.2.7 適用時の自動データ型変換
行論理変更レコード(行LCR)の列のデータ型と表の対応する列のデータ型が一致しない場合、適用プロセスによって、適用時に自動的に特定のデータ型が変換されます。
表4-4に、適用時に自動的に変換されるデータ型の組合せを示します。
表4-4 適用時に自動的に変換されるデータ型の組合せ
データ型 | CHARへ | NCHARへ | VARCHAR2へ | NVARCHAR2へ | CLOBへ | BLOBへ | DATEへ | TIMESTAMPへ |
---|---|---|---|---|---|---|---|---|
|
適用不可 |
はい |
はい |
はい |
はい |
いいえ |
いいえ |
いいえ |
|
はい |
適用不可 |
はい |
はい |
はい |
いいえ |
いいえ |
いいえ |
|
はい |
はい |
適用不可 |
はい |
はい |
いいえ |
いいえ |
いいえ |
|
はい |
はい |
はい |
適用不可 |
はい |
いいえ |
いいえ |
いいえ |
|
はい |
はい |
はい |
はい |
いいえ |
いいえ |
いいえ |
いいえ |
|
いいえ |
いいえ |
いいえ |
いいえ |
はい |
いいえ |
いいえ |
いいえ |
|
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
はい |
いいえ |
|
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
はい |
いいえ |
|
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
適用不可 |
はい |
|
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
いいえ |
はい |
適用不可 |
表4-4の組合せで「はい」が指定されている場合、適用プロセスはデータ型の組合せに対して自動的にデータ型変換を実行します。表4-4の組合せで「いいえ」が指定されている場合、適用プロセスはデータ型の組合せに対してデータ型変換を実行しません。たとえば、適用プロセスは自動的にCHAR
をNCHAR
に変換しますが、CHAR
をBLOB
には変換しません。
また、対応する表の列が行LCR列から変換した文字列を保持できるほど十分に大きくない場合は、適用プロセスでエラーが発生します。
次の各項では、適用時の自動データ型変換について詳しく説明します。
注意:
自動データ型変換を実行するには、適用プロセスはOracle Database 11g リリース1(11.1.0.7)以上に含まれている必要があります。ただし、以前のOracle Databaseリリースで取得または作成された行LCRの列は適用プロセスによって変換できます。
関連項目:
データ・タイプの詳細は、『Oracle Database SQL言語リファレンス』を参照してください。
4.2.7.1 適用時の文字データ型の自動トリミング
rtrim_on_implicit_conversion
適用プロセス・パラメータ では、適用プロセスがCHAR
またはNCHAR
をVARCHAR2
、NVARCHAR2
またはCLOB
に変換する場合にデータをトリミングするかどうかを決定します。このパラメータをY
に設定すると、適用プロセスはデータ型の変換時に列の右端から埋め込まれている空白を自動的に削除します。このパラメータをN
に設定すると、適用プロセスはデータ型の変換時に埋め込まれている空白を保持します。
次に例を示します。
-
行LCRでは、
CHAR(10)
列に「abc」
が格納されています。 -
行LCRの対応する表の列は
NVARCHAR2(10)
です。
rtrim_on_implicit_conversion
適用プロセス・パラメータをY
に設定すると、適用プロセスは表の列に「abc」
を挿入し、これらの文字の後に続く埋込みを削除します。rtrim_on_implicit_conversion
適用プロセス・パラメータをN
に設定すると、適用プロセスは表の列に「abc」
を挿入し、列の残りの領域を空白で埋めます。
4.2.8 SQL生成
SQL生成とは、行論理変更レコード(行LCR)内にカプセル化された変更を実行するのに必要なSQL文を生成する機能のことです。適用プロセスで、行LCRに含まれる挿入、更新または削除の各操作を実行するのに必要なSQL文を生成できます。
この項の内容は次のとおりです。
注意:
この項では、PL/SQLインタフェースを使用したSQL生成の使用について説明します。XStreamインタフェースを使用してSQL生成を使用することもできます。
関連項目:
-
SQL生成を使用するプロシージャDMLハンドラの例は、「プロシージャDMLハンドラの作成」を参照
-
XStreamでのSQL生成の使用の詳細は、『Oracle Database XStreamガイド』を参照
4.2.8.1 SQL生成を実行するためのインタフェース
行LCRに対してGET_ROW_TEXT
およびGET_WHERE_CLAUSE
メンバー・プロシージャを使用して、SQL生成を実行できます。PL/SQLインタフェースを使用すると、CLOB
データ型のSQLが生成されます。
4.2.8.2 SQL生成のフォーマット
SQL文は、インライン値またはバインド変数の2つのフォーマットのいずれかで生成できます。返されたSQL文が比較的小さい場合は、インライン値を使用します。SQL文が大きい場合は、バインド変数を使用します。この場合、バインド変数は、古い列値と新しい列値の両方を指すポインタを含む個別のリストで渡されます。
各インタフェースでのバインド変数の使用の詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』のGET_ROW_TEXT
およびGET_WHERE_CLAUSE
の各行LCRメンバー・プロシージャについての説明を参照してください。
注意:
インライン値で生成されたSQL文の場合は、SQLインジェクションが発生する可能性があります。SQLインジェクションとは、SQL文内のクライアント提供データを使用するアプリケーションを不正に利用する手法であり、これにより機密データを表示または操作するためにデータベースに不正にアクセスできるようになります。生成されたSQL文を実行する予定の場合は、バインド変数を使用することを強くお薦めします。SQLインジェクションの詳細は、『Oracle Database PL/SQL言語リファレンス』を参照してください。
4.2.8.3 SQL生成およびデータ型
SQL生成では、次のデータ型がサポートされています。
-
VARCHAR2
-
NVARCHAR2
-
NUMBER
-
FLOAT
-
DATE
-
BINARY_FLOAT
-
BINARY_DOUBLE
-
LONG
-
TIMESTAMP
-
TIME
WITH
TIME
ZONE
-
TIMESTAMP
WITH
LOCAL
TIME
ZONE
-
INTERVAL
YEAR
TO
MONTH
-
INTERVAL
DAY
TO
SECOND
-
RAW
-
LONG
RAW
-
CHAR
-
NCHAR
-
BASICFILE
記憶域を持つCLOB
-
BASICFILE
記憶域を持つNCLOB
-
BASICFILE
記憶域を持つBLOB
-
CLOB
として格納されたXMLType
注意:
SQL生成では、Oracle Database 12cで導入された拡張データ型はサポートしていません。
4.2.8.3.1 SQL生成および自動データ型変換
適用プロセスによって暗黙的データ型変換が実行され(可能な場合)、生成されたSQLはANSI規格に従います(可能な場合)。自動データ型変換では、次の点を考慮する必要があります。
-
NULL
は"NULL"
として指定します。 -
データ型
CHAR
、VARCHAR2
、NVARCHAR2
、NCHAR
、CLOB
およびNCLOB
では、一重引用符は二重引用符に変換されます(インライン値の場合)。 -
LONG
データはCLOB
データに変換されます。 -
LONG
RAW
データはBLOB
データに変換されます。
4.2.8.3.2 SQL生成とLOB、LONG、LONG RAWおよびXMLTypeの各データ型
LOB列に対するINSERT
およびUPDATE
操作では、適用プロセスにより、LOBアセンブリを使用してLOBチャンクが自動的にアセンブルされます。これらの操作の場合、生成されたSQLにはNULL
以外の空の値が含まれます。チャンク化された列の実際の値は、後続のLCRに到達します。チャンクごとに、適切な列に対して適切なSQL操作を実行する必要があります。
同様に、LONG
、LONG
RAW
およびXMLType
の各データ型に対して、適用プロセスによりNULL
以外の空の値が生成され、列の実際の値が後続のLCRのチャンクに到達します。チャンクごとに、適切な列に対して適切なSQL操作を実行する必要があります。
生成されたSQLのインライン・バージョンでは、LOB、LONG
、LONG
RAW
およびXMLType
の各データ型の列について、挿入と更新に対して次のSQLが生成されます。
-
CLOB
、NCLOB
およびLONG
の各データ型の列の場合:EMPTY_CLOB()
-
BLOB
およびLONG
RAW
の各データ型の列の場合:EMPTY_BLOB()
-
XMLType
列の場合:XMLTYPE.CREATEXML('xml /')
ここで、
xml
/
とはXMLチャンクのことです。
DML文を含むLCRが到達してから、これらの変更に対するデータが個別のチャンクに到達します。このような変更に対してWHERE
句を生成し、生成したWHERE
句を使用してチャンクに含まれる変更対象の行を識別できます。たとえば、PL/SQLでは、GET_WHERE_CLAUSE
行LCRメンバー・プロシージャを使用して、行変更に対してWHERE
句を生成できます。
INSERT
およびUPDATE
操作の場合は、生成されたWHERE
句によって挿入または更新後の行が識別されます。たとえば、hr.departments
表に対する次の更新の場合を考えます。
UPDATE hr.departments SET department_name='Management' WHERE department_name='Administration';
この変更に対して生成されたWHERE
句は、次のとおりです。
WHERE "DEPARTMENT_NAME"='Management'
DBMS_LOB
パッケージのサブプログラムによって実行されるピース単位のLOB操作(WRITE
、TRIM
およびERASE
の各プロシージャなど)の場合、生成されたSQLにはSELECT
FOR
UPDATE
文が含まれます。
たとえば、clob_col
に対するLOB_WRITE
操作では、次のようなSQLが生成されます。
SELECT "CLOB_COL" FROM "HR"."LOB_TAB" WHERE "N1"=2 FOR UPDATE
選択されるclob_col
は定義されている必要があります。LOBロケータを使用して、行LCRに続くLOBチャンクでピース単位のLOB操作を実行できます。
関連項目:
-
LOBアセンブリの詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
4.2.8.4 SQL生成およびキャラクタ・セット
LCRメソッドを使用する場合、SQLはデータベース・キャラクタ・セットで生成されます。INSERT
、UPDATE
、INTO
などのSQLキーワードは、キャラクタ・セットに応じて変更されることはありません。
関連項目:
-
JDBCでのデータ変換の詳細は、『Oracle Databaseグローバリゼーション・サポート・ガイド』を参照
-
SQLキーワードの詳細は、『Oracle Database SQL言語リファレンス』を参照
4.2.8.5 生成されたSQL文の例
この項では、生成されたSQL文の例を示します。
4.2.8.5.1 hr.employees表に対して生成されたSQL文の例
この項では、hr.employees
表に行われた変更に対して適用プロセスによって生成されたSQL文の例を示します。
この項では、次の例を示します。
注意:
生成されたSQLは単一行であり、フォーマットされていません。
例4-1 生成された挿入
次の挿入が実行されるとします。
INSERT INTO hr.employees (employee_id, last_name, email, hire_date, job_id, salary, commission_pct) VALUES (207, 'Gregory', 'pgregory@example.com', SYSDATE, 'PU_CLERK', 9000, NULL);
インライン値を使用して生成されたSQLは、次のとおりです。
INSERT INTO "HR"."EMPLOYEES"("EMPLOYEE_ID","FIRST_NAME","LAST_NAME", "EMAIL","PHONE_NUMBER","HIRE_DATE","JOB_ID","SALARY","COMMISSION_PCT", "MANAGER_ID","DEPARTMENT_ID" ) VALUES ( 207, NULL,'Gregory', 'pgregory@example.com', NULL , TO_DATE(' 2009-04-15','syyyy-mm-dd'), 'PU_CLERK',9000, NULL , NULL , NULL )
バインド変数を使用して生成されたSQLは、次のとおりです。
INSERT INTO "HR"."EMPLOYEES"("EMPLOYEE_ID","FIRST_NAME","LAST_NAME", "EMAIL","PHONE_NUMBER","HIRE_DATE","JOB_ID","SALARY", "COMMISSION_PCT","MANAGER_ID","DEPARTMENT_ID" ) VALUES ( :1 ,:2 ,:3 ,:4 ,:5 ,:6 ,:7 ,:8 ,:9 ,:10 ,:11 )
例4-2 生成された更新
次の更新が実行されるとします。
UPDATE hr.employees SET salary=10000 WHERE employee_id=207;
インライン値を使用して生成されたSQLは、次のとおりです。
UPDATE "HR"."EMPLOYEES" SET "SALARY"=10000 WHERE "EMPLOYEE_ID"=207 AND "SALARY"=9000
バインド変数を使用して生成されたSQLは、次のとおりです。
UPDATE "HR"."EMPLOYEES" SET "SALARY"=:1 WHERE "EMPLOYEE_ID"=:2 AND "SALARY"=:3
例4-3 生成された削除
次の削除が実行されるとします。
DELETE FROM hr.employees WHERE employee_id=207;
インライン値を使用して生成されたSQLは、次のとおりです。
DELETE FROM "HR"."EMPLOYEES" WHERE "EMPLOYEE_ID"=207 AND "FIRST_NAME" IS NULL AND "LAST_NAME"='Gregory' AND "EMAIL"='pgregory@example.com' AND "PHONE_NUMBER" IS NULL AND "HIRE_DATE"= TO_DATE(' 2009-04-15','syyyy-mm-dd') AND "JOB_ID"='PU_CLERK' AND "SALARY"=10000 AND "COMMISSION_PCT" IS NULL AND "MANAGER_ID" IS NULL AND "DEPARTMENT_ID" IS NULL
バインド変数を使用して生成されたSQLは、次のとおりです。
DELETE FROM "HR"."EMPLOYEES" WHERE "EMPLOYEE_ID"=:1 AND "FIRST_NAME"=:2 AND "LAST_NAME"=:3 AND "EMAIL"=:4 AND "PHONE_NUMBER"=:5 AND "HIRE_DATE"=:6 AND "JOB_ID"=:7 AND "SALARY"=:8 AND "COMMISSION_PCT"=:9 AND "MANAGER_ID"=:10 AND "DEPARTMENT_ID"=:11
4.2.8.5.2 LOB列のある表に対して生成されたSQL文の例
この項では、次の表に行われた変更に対して適用プロセスによって生成されたSQL文の例を示します。
CREATE TABLE hr.lob_tab( n1 number primary key, clob_col CLOB, nclob_col NCLOB, blob_col BLOB);
この項では、次の例を示します。
注意:
生成されたSQLは単一行であり、フォーマットされていません。
GET_WHERE_CLAUSE
メンバー・プロシージャを使用すると、この挿入に対して次のWHERE
句が生成されます。
-
インラインの場合:
WHERE "N1"=2
-
バインド変数の場合:
WHERE "N1"=:1
WHERE
句を使用して、後続のチャンクがLOB列の変更に到達するときに挿入された行を識別できます。
例4-4 LOB列のある表に対して生成された挿入
次の挿入が実行されるとします。
INSERT INTO hr.lob_tab VALUES (2, 'test insert', NULL, NULL);
インライン値を使用して生成されたSQLは、次のとおりです。
INSERT INTO "HR"."LOB_TAB"("N1","BLOB_COL","CLOB_COL","NCLOB_COL" ) VALUES ( 2,, EMPTY_CLOB() ,)
バインド変数を使用して生成されたSQLは、次のとおりです。
INSERT INTO "HR"."LOB_TAB"("N1","BLOB_COL","CLOB_COL","NCLOB_COL" ) VALUES ( :1 ,:2 ,:3 ,:4 )
例4-5 LOB列のある表に対して生成された更新
次の更新が実行されるとします。
UPDATE hr.lob_tab SET clob_col='test update' WHERE n1=2;
インライン値を使用して生成されたSQLは、次のとおりです。
UPDATE "HR"."LOB_TAB" SET "CLOB_COL"= EMPTY_CLOB() WHERE "N1"=2
バインド変数を使用して生成されたSQLは、次のとおりです。
UPDATE "HR"."LOB_TAB" SET "CLOB_COL"=:1 WHERE "N1"=:2
例4-6 LOB列のある表に対して生成された削除
次の削除が実行されるとします。
DELETE FROM hr.lob_tab WHERE n1=2;
インライン値を使用して生成されたSQLは、次のとおりです。
DELETE FROM "HR"."LOB_TAB" WHERE "N1"=2
バインド変数を使用して生成されたSQLは、次のとおりです。
DELETE FROM "HR"."LOB_TAB" WHERE "N1"=:1
4.2.9 Oracle Streamsの適用プロセスおよびRESTRICTED SESSION
システム起動時にSTARTUP
RESTRICT
文を発行して制限付きセッションを有効にすると、データベースの停止時に適用プロセスが実行中であった場合でも、適用プロセスは起動されません。制限付きセッションを無効にすると、停止されていない各適用プロセスが起動されます。
SQL文ALTER
SYSTEM
ENABLE
RESTRICTED
SESSION
によって実行中のデータベースで制限付きセッションを有効にしても、実行中の適用プロセスには影響がありません。これらの適用プロセスは引き続き実行され、メッセージの適用が行われます。停止した適用プロセスを制限付きセッションで起動しても、この適用プロセスは、制限付きセッションを無効にするまで実際には起動されません。
4.2.10 適用プロセスのサブコンポーネント
適用プロセスのサブコンポーネントは、次のとおりです。
-
メッセージをデキューするリーダー・サーバー。リーダー・サーバーは、論理変更レコード(LCR)間の依存性を計算してメッセージをトランザクションにアセンブルするプロセスです。その後、リーダー・サーバーは、アセンブルしたトランザクションをコーディネータ・プロセスに返します。
-
リーダー・サーバーからトランザクションを取得して適用サーバーに渡すコーディネータ・プロセス。コーディネータ・プロセス名は
AP
nn
(nn
は文字および数字)です。コーディネータ・プロセスはOracleバックグラウンド・プロセスです。 -
LCRをDML文またはDDL文としてデータベース・オブジェクトに適用するか、LCRを適切な適用ハンドラに渡す1つ以上の適用サーバー。LCR以外のメッセージの場合、適用サーバーはメッセージをメッセージ・ハンドラに渡します。適用サーバーは、
DBMS_APPLY_ADM.SET_ENQUEUE_DESTINATION
プロシージャで指定されたキューの永続キュー部分にLCRメッセージとLCR以外のメッセージをエンキューすることもできます。各適用サーバーはプロセスです。適用サーバーにエラーが発生すると、ユーザー指定の競合ハンドラまたはエラー・ハンドラを使用してエラーを解決しようとします。エラーを解決できない場合は、トランザクションをロールバックして、すべてのメッセージを含めトランザクション全体をエラー・キューに配置する。適用サーバーが完了済トランザクションをコミットした場合、そのトランザクションは適用される。トランザクションをエラー・キューに配置してコミットした場合にも、トランザクションは適用される。
リーダー・サーバーおよび適用サーバー・プロセス名はAS
nn
であり、nn
には文字および数字を含めることができます。適用サーバーで処理されているトランザクションに、適用されているかどうかが不明な別のトランザクションとの依存関係がある場合、適用サーバーはコーディネータ・プロセスに接続して指示を待ちます。コーディネータ・プロセスは、トランザクションが正しい順序で適用およびコミットされていることを確認するため、すべての適用サーバーを監視します。
次の各項では、適用プロセスの各サブコンポーネントの考えられる状態について説明します。
関連項目:
4.2.10.1 リーダー・サーバーの状態
リーダー・サーバーの状態は、リーダー・サーバーが現在行っている処理を示します。適用プロセスのリーダー・サーバーの状態は、V$STREAMS_APPLY_READER
動的パフォーマンス・ビューを問い合せることによって表示できます。リーダー・サーバーの状態は次のいずれかになります。
-
INITIALIZING
- 起動中 -
IDLE
: 実行中の作業なし。 -
DEQUEUE
MESSAGES
: 適用プロセスのキューからメッセージをデキュー中 -
SCHEDULE
MESSAGES
: メッセージ間の依存性を計算して、メッセージをトランザクションにアセンブル中 -
SPILLING
: 適用されていないメッセージがメモリーからハード・ディスクにオーバーフロー中 -
PAUSED
-
WAITING
FOR
DDL
TO
COMPLETE
- DDL LCRが適用されるのを待つために一時停止中
関連項目:
-
適用プロセスのリーダー・サーバーの状態を表示する問合せの詳細は、「各適用プロセスのリーダー・サーバーに関する情報の表示」を参照
4.2.10.2 コーディネータ・プロセスの状態
コーディネータ・プロセスの状態は、コーディネータ・プロセスが現在行っている処理を示します。コーディネータ・プロセスの状態は、V$STREAMS_APPLY_COORDINATOR
動的パフォーマンス・ビューを問い合せることによって表示できます。コーディネータ・プロセスの状態は次のいずれかになります。
-
INITIALIZING
: 起動しています。 -
IDLE
: 実行中の作業なし。 -
APPLYING
: 適用サーバーにトランザクションを引渡し中 -
SHUTTING
DOWN
CLEANLY
: 停止中(エラーなし) -
ABORTING
: 適用エラーのために停止中
関連項目:
-
コーディネータ・プロセスの状態を表示する問合せの詳細は、「各コーディネータ・プロセスに関する一般情報の表示」を参照
4.2.10.3 適用サーバーの状態
適用サーバーの状態は、適用サーバーが現在行っている処理を示します。適用プロセスの各適用サーバーの状態は、V$STREAMS_APPLY_SERVER
動的パフォーマンス・ビューを問い合せることによって表示できます。適用サーバーの状態は次のいずれかになります。
-
INITIALIZING
: 起動しています。 -
IDLE
: 実行中の作業なし。 -
RECORD
LOW-WATERMARK
: 適用の進捗に関する情報をメンテナンスする管理操作を実行中。この情報は、ALL_APPLY_PROGRESS
およびDBA_APPLY_PROGRESS
データ・ディクショナリ・ビューで使用されます。 -
ADD
PARTITION
: 進行中のトランザクションに関する情報の記録に使用されるパーティションを追加する管理操作を実行中。 -
DROP
PARTITION
: 進行中のトランザクションに関する情報の記録に使用されたパーティションを削除する管理操作を実行中。 -
EXECUTE
TRANSACTION
: トランザクションを適用中。 -
WAIT
COMMIT
: コミットSCNが小さい、他のすべてのトランザクションが適用されるまで、トランザクションのコミットを待機中。commit_serialization
適用プロセス・パラメータがDEPENDENT_TRANSACTIONS
以外の値に設定され、parallelism
適用プロセス・パラメータが1
より大きい値に設定された場合にのみ、この状態は発生します。 -
WAIT
DEPENDENCY
: 依存関係にある別のトランザクションが適用されるまで、トランザクション内のLCRの適用を待機中。PARALLELISM
適用プロセス・パラメータが1
より大きい値に設定されている場合のみ、この状態は発生します。 -
WAIT
FOR
CLIENT
: XStream Inクライアント・アプリケーションが論理変更レコード(LCR)をさらにリクエストしてくるのを待機中。 -
WAIT
FOR
NEXT
CHUNK
: 大規模なトランザクションの次のLCRのセットを待機中。 -
ROLLBACK
TRANSACTION
: トランザクションのロールバック中。 -
TRANSACTION
CLEANUP
: 適用済トランザクションのクリーンアップ中(適用プロセスのキューからのLCRの削除も含む)。
関連項目:
-
各適用プロセスの適用サーバーの状態を表示する問合せの詳細は、「各適用プロセスの適用サーバーに関する情報の表示」を参照
-
適用プロセス・パラメータの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
4.2.11 適用ユーザー
メッセージは、適用プロセスの適用ユーザーのセキュリティ・ドメインで適用されます。適用ユーザーは、適用プロセスのルール・セットを満たすすべてのメッセージをデキューします。適用ユーザーは、メッセージをデータベース・オブジェクトに直接適用できます。また、適用ユーザーは、これらのルール・セットのルールで指定されたすべてのカスタム・ルールベースの変換を実行します。ユーザー定義の適用ハンドラも実行します。
適用ユーザーは、次の権限を含む、変更の適用に必要な権限を持っている必要があります。
-
適用プロセスで使用するルール・セットの
EXECUTE
権限 -
ポジティブ・ルール・セットのルールに指定されているすべてのカスタム・ルールベースの変換ファンクションの
EXECUTE
権限 -
すべての適用ハンドラの
EXECUTE
権限 -
適用プロセスのキューからメッセージをデキューする権限
適用プロセスは1ユーザーのみに関連付けることができますが、1ユーザーは複数の適用プロセスと関連付けることができます。
関連項目:
-
必要な権限の詳細は、『Oracle Streamsレプリケーション管理者ガイド』を参照
4.2.12 適用プロセス・パラメータ
適用プロセスの作成後、適用プロセスは、最初の起動前に環境に合わせて適用プロセス・パラメータを設定できるように無効になっています。適用プロセス・パラメータによって、適用プロセスの動作が制御されます。たとえば、parallelism適用プロセス・パラメータによって、トランザクションを同時に適用できる適用サーバーの数が指定され、time_limit
適用プロセス・パラメータによって、適用プロセスが自動的に停止されるまでの実行時間が指定されます。適用プロセス・パラメータを設定した後、適用プロセスを起動できます。
関連項目:
-
すべての適用プロセス・パラメータの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照
4.2.13 データベースの再起動時における適用プロセスの永続的状態
適用プロセスを実行しているデータベースが停止され、再起動されても、適用プロセスは永続的状態を保ちます。たとえば、データベースの停止時に適用プロセスを有効にすると、その適用プロセスはデータベースの再起動時に自動的に開始されます。同様に、データベースの停止時に適用プロセスを無効にするか、または強制終了させると、その適用プロセスはデータベースが再起動されても開始されず、無効または強制終了の状態のままとなります。
4.2.14 エラー・キュー
エラー・キューには、1つのデータベースの現在の適用エラーがすべて格納されます。データベースに複数の適用プロセスが存在する場合、エラー・キューには各適用プロセスの適用エラーが格納されます。適用エラーに関する情報を表示するには、DBA_APPLY_ERROR
データ・ディクショナリ・ビューを問い合せるか、Oracle Enterprise Manager Cloud Controlを使用します。
エラー・キューには、データベースで実行中の適用プロセスによって正常に適用できなかったトランザクションに関する情報が格納されます。1つのトランザクションには、多数のメッセージが含まれる可能性があります。適用中に未処理エラーが発生すると、適用プロセスのルール・セットを満たすトランザクション内のすべてのメッセージがエラー・キューに自動的に移されます。
エラーの原因となった状態を修正し、エラー・トランザクションを再実行できます。たとえば、表の1行を変更して、エラーの原因となった状態を修正できる場合もあります。
エラーの原因となった条件を訂正した後、EXECUTE_ERROR
またはEXECUTE_ALL_ERRORS
プロシージャを使用してエラー・キュー内のトランザクションを再実行するか、またはDELETE_ERROR
やDELETE_ALL_ERRORS
プロシージャを使用してエラー・キューからトランザクションを削除できます。これらのプロシージャは、DBMS_APPLY_ADM
パッケージに含まれています。
エラー・キュー内のトランザクションを再実行する場合は、そのトランザクションを実行するユーザーとして、最初にエラー・キューにエラーを置いたユーザーまたはトランザクションを再実行するユーザーを指定できます。また、エラー・キュー内のトランザクションを再実行する場合は、適用プロセスの現行のOracle Streamsタグが使用されます。
再実行のトランザクションでは、適用ハンドラと競合解決ハンドラを関連付けて使用できます。たとえば、エラーの解決策として、エラー・キュー内の行LCRが実行前に変更されるようにするには、エラーの原因となった行LCRをエラー・キュー内で処理するようにプロシージャDMLハンドラを構成します。つまり、DMLハンドラに行LCRを修正させることで、同じエラーの繰返しを回避できます。行LCRを含んだエラーが再実行されると、その行LCRはDMLハンドラに渡されます。その後、たとえば文DMLハンドラであれば、行LCRが示す挿入とは異なる値を挿入することができますし、プロシージャDMLハンドラを使用すれば、行LCR内の1つ以上の列を修正することによって、同じエラーの繰返しを回避することができます。
エラー・キューには、ローカルの宛先データベースのみで発生したエラーに関する情報が格納されます。Oracle Streams環境の他のデータベースで実行中の適用プロセスに関するエラー情報は格納されません。
エラー・キューは、データベースの例外キューを使用します。DBMS_STREAMS_ADM
パッケージのSET_UP_QUEUE
プロシージャを使用してANYDATA
キューを作成する際にキューのキュー表が存在しない場合は、プロシージャによって作成されます。キュー表が作成されると、キュー表の例外キューが自動的に作成されます。1つのキュー表を複数のキューで使用できます。また、各キュー表には1つの例外キューがあります。したがって、1つの例外キューで、複数のキューおよび複数の適用プロセスのエラーを格納できます。
例外キューには自身のキュー表に対する適用エラーのみが格納されますが、Oracle Streamsエラー・キューにはデータベースの各例外キュー内のすべての適用エラーに関する情報が格納されます。Oracle Streams適用エラーを管理するには、DBMS_APPLY_ADM
パッケージ内のプロシージャを使用する必要があります。適用エラーは例外キューから直接デキューしないでください。
注意:
メッセージ・クライアントは、メッセージのデキュー時にエラーが発生すると、自身のキュー表に関連付けられている例外キューにこれらのメッセージを移動します。ただし、メッセージ・クライアントのエラーに関する情報はエラー・キューには格納されません。適用プロセスのエラーに関する情報のみがエラー・キューに格納されます。
関連項目:
-
「適用エラーの管理」
-
DBMS_APPLY_ADM
パッケージの詳細は、『Oracle Database PL/SQLパッケージおよびタイプ・リファレンス』を参照 -
DBA_APPLY_ERROR
データ・ディクショナリ・ビューの詳細は、『Oracle Databaseリファレンス』を参照
4.3 メッセージ・クライアントによる明示的コンシューム
メッセージ・クライアントは、アプリケーションまたはユーザーに起動されたときに永続キューからメッセージをデキューします。ルールを使用して、メッセージ・クライアントによってキューからデキューされるメッセージを指定できます。このようなメッセージは、永続LCRまたは永続ユーザー・メッセージです。
メッセージ・クライアントを作成するには、DBMS_STREAMS_ADM
パッケージの次のいずれかのプロシージャを実行するときにstreams_type
パラメータにdequeue
を指定します。
メッセージ・クライアントを作成するとき、メッセージ・クライアントの名前と、メッセージ・クライアントがメッセージをデキューするANYDATA
キューを指定します。これらのプロシージャを使用して、メッセージ・クライアントのポジティブ・ルール・セットまたはネガティブ・ルール・セットにルールを追加することもできます。ルールごとにメッセージ・タイプを指定すると、1つのメッセージ・クライアントで様々なタイプのメッセージをデキューできます。
メッセージ・クライアントを作成するユーザーは、そのメッセージ・クライアントを使用してキューからデキューする権限を付与されます。このユーザーは、メッセージ・クライアント・ユーザーです。メッセージ・クライアント・ユーザーは、メッセージ・クライアントのルール・セットを満たすメッセージをデキューできます。1つのメッセージ・クライアントを関連付けることができるのは1ユーザーのみですが、1人のユーザーには多数のメッセージ・クライアントを関連付けることができます。
図4-2に、メッセージをデキューするメッセージ・クライアントを示します。
関連項目:
-
DBMS_AQ
パッケージに関する情報は『Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド』を参照
4.4 手動デキューによる明示的コンシューム
手動デキューによる明示的コンシュームでは、アプリケーションはバッファLCR、永続LCR、バッファ・ユーザー・メッセージまたは永続ユーザー・メッセージを手動で明示的にデキューして処理します。メッセージがデキューされるキューは、ANYDATAキューまたは型付きキューです。DBMS_STREAMS_MESSAGING
パッケージまたはDBMS_AQ
パッケージを使用してメッセージをデキューできます。
Oracle Databaseアドバンスト・キューイングのデキューでは、次のような機能を利用できます。
-
バッファ・キューまたは永続キューからのデキュー
-
同時デキュー
-
デキュー方法
-
デキュー・モード
-
メッセージ配列をデキューします。
-
メッセージの状態
-
デキュー時のメッセージの操作
-
メッセージの待機
-
遅延の再試行
-
トランザクション保護(オプション)
-
例外キュー
関連項目:
-
これらの機能およびOracle Databaseアドバンスト・キューイングで利用できるその他の機能の詳細は、『Oracle Databaseアドバンスト・キューイング・ユーザーズ・ガイド』を参照