Oracle Database アダプターでポーリング ベースのデータ変更メッセージを受信する

Microsoft BizTalk Adapter for Oracle Database では、Oracle データベースのポーリングによるポーリング ベースのデータ変更メッセージの受信がサポートされています。 アダプターは、次の方法でメッセージをアプリケーションに配信します。

  • SQL SELECT クエリを実行して、データがポーリングに使用できるかどうかを判断します。 SQL SELECT クエリを定期的または継続的に実行するようにアダプターを構成できます。

  • Oracle テーブルまたはビューに対して SQL SELECT クエリを実行するか、ストアド プロシージャ、関数、またはパッケージ化されたプロシージャと関数を実行する。

  • Oracle データベースでオプションのポーリング後 PL/SQL コード ブロックを実行する。 このコード ブロックは、多くの場合、ターゲット内のクエリ対象レコードのフィールドを更新したり、クエリされたレコードを別のテーブルまたはビューに移動したりするために使用されます。

  • クエリを返すと、POLLINGSTMT 操作、またはポーリング操作として公開されるストアド プロシージャ、関数、パッケージ化されたプロシージャ、または関数を呼び出すことによって、結果セットが返されます。

    アダプターは、Oracle トランザクション内でこれらすべての操作を実行します。

    アダプターを使用すると、接続 URI で パラメーターを公開 PollingId することで、同じアプリケーション内の複数の Oracle 成果物のデータ変更メッセージを受信することもできます。 このパラメーターは、POLLINGSTMT 操作のターゲット名前空間を変更します。

POLLINGSTMT のターゲット名前空間を変更する

接続 URI にクエリ文字列パラメーターを設定することで、POLLINGSTMT 操作の PollingId ターゲット名前空間を変更できます。 PollingId接続 URI に が指定されている場合、Oracle Database アダプターは、 パラメーターで指定された文字列を PollingId POLLINGSTMT 操作http://microsoft.lobservices.oracledb/2007/03/POLLINGSTMTの既定のターゲット名前空間に追加します。 POLLINGSTMT 操作のメッセージ・アクションは変更されません。

たとえば、次の接続 URI が指定されている場合、 OracleDb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivityターゲット名前空間は になります http:/microsoft.lobservices.oracledb/2007/03/POLLINGSTMTAcctActivity

POLLINGSTMT 操作ごとに一意の名前空間を指定することで、アプリケーション内の複数の Oracle テーブルとビューのデータ変更メッセージを受信できます。

Oracle Database アダプター接続 URI の詳細については、「 Oracle Database 接続 URI の作成」を参照してください。

バインド プロパティを使用してデータ変更メッセージを受信する

データ変更メッセージを受信するように Oracle Database アダプターを構成するには、次のバインド プロパティの一部またはすべてを設定します。

Binding プロパティ 既定 必須/省略可能
InboundOperationType 値が [ポーリング] に設定されていることを確認します。 ポーリング 必須。 明示的に設定しない場合、既定値が適用されます。
PolledDataAvailableStatement 実行される SELECT ステートメントを指定して、特定のテーブルのポーリングに使用できるデータがあるかどうかを判断します。 指定したステートメントは、行と列で構成される結果セットを返す必要があります。 結果セットの最初のセルの値は、アダプターが PollingStatement バインディング プロパティに指定された値を実行するかどうかを示します。 結果の最初のセルに正の値が含まれている場合、アダプターはポーリング ステートメントを実行します。 たとえば、このバインディング プロパティの有効なステートメントは次のようになります。

Select * from <table_name>

メモ: このバインド プロパティにはストアド プロシージャを指定しないでください。 また、このステートメントでは、基になる Oracle データベースを変更しないでください。
デュアルから 1 を選択する 必須。 明示的に設定されていない場合、既定値が適用されます。つまり、ポーリング対象のテーブルにデータがあるかどうかに関係なく、アダプターがポーリングを続行する必要があることを意味します。
PollingAction ポーリング操作のアクションを指定します。 アダプター サービス アドインを使用して、操作に対して生成するメタデータから、特定の操作のポーリング アクションを決定できます。 null SELECT ステートメントを使用してテーブルとビューに対するポーリング操作を行う場合は省略可能です。
PollingInterval アダプターが Oracle データベースに対してクエリを実行する間隔 (秒単位) に設定します。 このプロパティは、ポーリング間隔とポーリング トランザクションのタイムアウトを指定します。値は、Oracle データベースでクエリとポーリング後のステートメントを実行するのにかかる時間 (指定されている場合) と、クライアントがクエリ データを処理してポーリング応答メッセージを返すのにかかる時間を超える必要があります。 500 必須。 明示的に設定しない場合、既定値が適用されます。
PollingStatement 次のいずれかを指定します。

- Oracle データベースに対して実行する必要がある SQL SELECT ステートメント。 このステートメントには、FOR UPDATE 句を含める必要があります。 FOR UPDATE 句の詳細については、このトピックで後述 するポーリング ステートメントの FOR UPDATE 句の指定 に関するページを参照してください。

- ポーリングするパッケージ内のストアド プロシージャ、関数、またはプロシージャまたは関数のメッセージを要求します。
null 必須。 PollingStatement を null 以外の値に設定すると、ポーリングが有効になります。
PollWhileDataFound ポーリング対象のテーブルでデータが使用可能な場合に、Oracle Database アダプターがポーリング間隔を無視し、Oracle データベースを継続的にポーリングするかどうかを指定します。 テーブルに使用可能なデータがない場合、アダプターは指定されたポーリング間隔で SQL ステートメントを実行するように戻ります False 必須。 明示的に設定しない場合、既定値が適用されます。
PostPollStatement クエリが実行された後、クエリ データがクライアントに返される前にアダプターによって実行される省略可能な PL/SQL コード ブロックに設定します。 null 省略可能。 値が指定されていない場合、post poll ステートメントは実行されません。

Note

WCF サービス モデルまたは WCF チャネル モデルを使用している場合は、 AcceptCredentialsInUri バインド プロパティも設定する必要があります。

ポーリング ステートメントに FOR UPDATE を入力します

SELECT ステートメントをポーリング ステートメントとして使用し、SELECT ステートメントで指定された行に影響を与えるポーリング後ステートメントを実行する場合は、ポーリング ステートメントで FOR UPDATE 句を使用する必要があります。 FOR UPDATE 句を指定すると、ポーリング ステートメントによって選択されたレコードがトランザクション中にロックされ、ポーリング後ステートメントで必要な更新を実行できるようになります。

注意事項

ポーリングステートメントとポーリング後ステートメントの間の時間枠で、ポーリング後ステートメントの条件を満たすレコードがテーブルに追加されるシナリオを作成できます。 このような状況では、ポーリング後ステートメントは、ポーリング ステートメントの一部として選択されたレコードだけでなく、条件を満たすすべてのレコードを更新します。

ポーリング後ステートメントが指定されていて、ポーリング ステートメントに FOR UPDATE 句が含まれていない場合は、次の 2 つの条件のいずれかが発生します。

  • TransactionIsolationLevelReadCommitted に設定されている場合、ポーリング後のクエリでは、選択した行は更新されません。

  • TransactionIsolationLevelSerializable に設定されている場合、ポーリング後のステートメントが実行されたときに、"ORA-08177 はこのトランザクションのアクセスをシリアル化できません" というターゲット システム例外 (Microsoft.ServiceModel.Channels.Common.TargetSystemException) が発生します。 このような場合は、 PollingRetryCount バインド プロパティを設定して、アダプターが同じトランザクションを再試行する回数を定義する必要があります。

    トランザクション分離レベルを設定する手順については、「 Oracle Database でトランザクション分離レベルとトランザクション タイムアウトを構成する」を参照してください。

    ポーリングステートメントとポーリング後ステートメントは、アダプター クライアントがトランザクションを使用するように構成されており、アダプターの UseAmbientTransaction バインディング プロパティの値が True に設定されている場合、トランザクションで実行されます。

    FOR UPDATE オプションを使用したポーリング クエリの例を次に示します。

SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE  

ポーリング ステートメントに NOWAIT 句を入力します

同時実行スレッドがポーリング対象のテーブルにアクセスし、テーブル内の競合が多すぎる場合があります。 これにより、ポーリング クエリがブロックされ、テーブル行に対するロックが取得される可能性があります。 ポーリング ステートメントとして SELECT ステートメントを使用している場合は、SELECT ステートメントで FOR UPDATE キーワード (keyword)と共に NOWAIT キーワード (keyword)を指定できます。 これにより、ポーリング クエリが選択しようとしている行にロックがある場合、アダプター内でのポーリング クエリの実行が直ちに返されます。 通常、このような条件下では Oracle によって例外がスローされます。 この場合も、アダプター クライアントは PollingInterval バインディング プロパティを使用して、アダプター クライアントがデータのポーリングを再試行する必要がある時間間隔を指定できます。

NOWAIT オプションを使用したポーリング クエリの例を次に示します。

SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE NOWAIT  

ポーリング ステートメントに SKIP LOCKED 句を入力します

ポーリング対象のテーブルにアクセスする同時実行スレッドが原因で、ポーリング クエリで指定された WHERE 句の結果セット内の一部の行がロックされている場合があります。 たとえば、ポーリング クエリはテーブルから 6 行を返します。これらの 6 行のうち 4 行は、他のトランザクションのために既にロックされています。 この場合は、SKIP LOCKED キーワード (keyword)と FOR UPDATE キーワード (keyword)を指定して、WHERE 句で指定された行をロックし、既にロックされている行をスキップするようにデータベースに指示できます。 WHERE 句のロック解除された行はトランザクション中にロックされ、ポーリング後ステートメントは必要な更新を実行して、これらの行が再度ポーリングされないようにすることができます。 これにより、WHERE 句で指定されたすべての行がロック解除されるまで、ポーリング メッセージの受信を待機する必要はありません。

SKIP LOCKED キーワード (keyword)は、データベース内の同じテーブルをポーリングしている複数のコンピューターにアダプター クライアントがある場合に便利です。 ポーリング操作を構成して、その時点でロックが解除された WHERE 句で指定された行のポーリング ベースのデータ変更メッセージを受信するようにアダプター クライアント間で負荷分散を行い、その行を更新して、ポーリング ベースのデータ変更メッセージがアダプター クライアントによって受信された場合に確実に行を更新できます。 他のクライアントは同じメッセージを受け取りません。

SKIP LOCKED オプションを使用したポーリング クエリの例を次に示します。

SELECT * from EMP WHERE FLAG = 'Y' FOR UPDATE SKIP LOCKED  

注文済み配信 (FIFO) のサポート

運用環境では、ポーリングを使用して Oracle データベースのデータ変更を監視できます。 これらのデータ変更メッセージは、Oracle Database アダプターを使用してアダプター クライアントによって受信されます。 ビジネス シナリオに基づいて、データ変更メッセージをアダプター クライアントが適切な順序で受信することが重要な場合があります。

Oracle Database アダプターは、Oracle データベースからメッセージを受信する順序を維持するために、順序付けされた配信または先入れ先出し (FIFO) をサポートしています。 Oracle Database アダプターの受信シナリオでの FIFO のサポートに関連するいくつかの考慮事項を次に示します。

  • メッセージがオーケストレーションによって使用されている場合、オーケストレーションには、Oracle Database アダプターの受信ポートから送信されるメッセージの順序付き配信セットが必要です。

  • メッセージが送信ポート (コンテンツ ベースのルーティング) シナリオで使用されている場合、送信ポートには、Oracle Database アダプターの受信ポートから送信されるメッセージに対して順序付けされた配信セットが必要です。

    WCF-Custom アダプターまたは WCF-OracleDB アダプターには、受信処理に 失敗した要求メッセージを中断 するかどうかを指定する"失敗時の要求メッセージの中断" プロパティがあります。 このプロパティは、WCF-Custom の [ メッセージ ] タブで設定することも、[ エラー処理 ] セクションで受信ポート WCF-OracleDB 設定することもできます。 次の表に、このプロパティが設定されているかどうかとメッセージ サブスクライバーの状態 (オーケストレーションまたはポート) に基づいて受信メッセージがどのように処理されるかを説明するシナリオを示します。

Port プロパティ 登録されていない状態のサブスクライバー 参加済みだが停止状態のサブスクライバー
失敗時に要求メッセージを中断 する プロパティが設定されていません - ルーティング エラー レポートが中断された (再開できないメッセージ) として生成される

- 実際のメッセージが中断されない

- ポーリング後のクエリは、トランザクションが中止されるため実行されません。 そのため、ポーリングは繰り返し行をフェッチします。

- 発生した内容を説明するためにイベント ログで報告されたエラー。
- "失敗" とは見なされません。 イベント ログにエラー メッセージはありません。

- 実際のメッセージは、中断 (再開可能) キューに格納されます。

- サブスクライブ ポートまたはオーケストレーションが開始されると、メッセージは自動的に再開されます。 サブスクライバーで順序付けされた配信が設定されている場合は、受け入れられます。

- メッセージは手動で再開することもできます。
エラー プロパティ IS セットの要求メッセージを中断する - ルーティング エラー レポートが中断された (再開できないメッセージ) として生成される

- 実際のメッセージも中断されています

- ポーリング後のクエリは、トランザクションが中止されるため実行されません。 そのため、ポーリングは繰り返し行をフェッチします。

- 発生した内容を説明するためにイベント ログで報告されたエラー。
- "失敗" とは見なされません。 イベント ログにエラー メッセージはありません。

- 実際のメッセージは、中断 (再開可能) キューに格納されます。

- サブスクライブ ポートまたはオーケストレーションが開始されると、メッセージは自動的に再開されます。 サブスクライバーで順序付けされた配信が設定されている場合は、受け入れられます。

- メッセージは手動で再開することもできます。

こちらもご覧ください

Oracle データベース アプリケーションの開発
BizTalk Serverを使用して Oracle Database をポーリングする
WCF サービス モデルを使用して Oracle Database でポーリング ベースのデータ変更メッセージを受信する
WCF チャネル モデルを使用して Oracle Database でポーリング ベースのデータ変更メッセージを受信する