WCF サービス モデルを使用して Oracle Database でポーリング ベースのデータ変更メッセージを受信する

Oracle テーブルまたはビューに対してポーリング ベースのデータ変更メッセージを受信するように Microsoft BizTalk Adapter for Oracle Database を構成できます。 データ変更メッセージを受信するために、アダプターは Oracle テーブルまたはビューに対して SQL クエリを定期的に実行し、その後にオプションの PL/SQL コード ブロックを実行します。 SQL クエリの結果は、Oracle Database アダプターによって、受信 POLLINGSTMT 操作で厳密に型指定された結果セットとしてアプリケーションに返されます。 Oracle データベース アダプターを使用して Oracle データベースのポーリングを構成および実行するために使用されるメカニズムの詳細については、「 Oracle Database アダプターでポーリング ベースのデータ変更メッセージを受信する」を参照してください。 先に進む前に、このトピックを読むことを強くお勧めします。

WCF サービス モデルを使用するときに POLLINGSTMT 操作を受信するには、次の操作を行う必要があります。

  • アダプターによって公開されるメタデータから POLLINGSTMT 操作の WCF サービス コントラクト (インターフェイス) を生成します。 これを行うには、アダプター サービス参照の追加 Visual Studio プラグインまたは ServiceModel メタデータ ユーティリティ ツール (svcutil.exe) を使用します。

  • このインターフェイスから WCF サービスを実装します。

  • サービス ホスト (System.ServiceModel.ServiceHost) を使用して、この WCF サービスをホストします。

    このセクションのトピックでは、WCF サービス モデルの Oracle データベース テーブルとビューに対してポーリングを実行するのに役立つ情報と手順について説明します。

このトピックで使用する例について

このトピックの例では、/SCOTT/ACCOUNTACTIVITY テーブルと /SCOTT/Package/ACCOUNT_PKG/PROCESS_ACTIVITY 関数を使用します。 これらの成果物を生成するスクリプトは、BizTalk アダプター パックのサンプルと共に提供されています。 サンプルの詳細については、「 アダプターのサンプル」を参照してください。

WCF サービス モデルでのポーリングの構成

Oracle データベース のテーブルとビューに対してポーリングを実行するように Oracle Database アダプターを構成するには、バインド プロパティとオプションの接続プロパティ (パラメーター) を設定します。 これらのプロパティの一部は必須であり、一部のプロパティはデザイン時と実行時の両方で設定する必要があります。

  • 設計時に、Oracle Database に接続して WCF サービス コントラクトを生成するときに、接続パラメーターとバインド プロパティを設定します。

  • 実行時に、サービス ホストの作成に使用する OracleDBBinding オブジェクトにバインド プロパティを設定します。 接続パラメーターは、サービス ホストにサービス リスナーを追加するときに設定します。

    次の一覧は、ポーリングの構成に使用されるバインド プロパティと接続パラメーターの概要を示しています。

  • PollingStatement バインド プロパティ。 このバインディング プロパティは、デザイン時と実行時の両方に設定する必要があります。

  • 省略可能なバインド プロパティ。 これらは実行時にのみ設定する必要があります。

  • AcceptCredentialsInUri バインド プロパティ。 接続 URI で資格情報を有効にする場合は、実行時にこのバインド プロパティを true に設定する必要があります。 サービス エンドポイントをサービス ホストに追加するときは、接続 URI にユーザー名とパスワードが存在する必要があります。

  • 接続 URI の PollingId クエリ文字列パラメーター。 POLLINGSTMT 操作の名前空間を変更する場合は、デザイン時と実行時の両方でこの接続プロパティを設定する必要があります。

    ポーリングの構成に使用されるバインド プロパティと接続パラメーターの詳細については、「 Oracle Database アダプターでポーリング ベースのデータ変更メッセージを受信する」を参照してください。

WCF サービス コントラクトとクラス

アダプター サービス参照の追加 Visual Studio プラグインまたは ServiceModel メタデータ ユーティリティ ツール (svcutil.exe) を使用して、WCF サービス コントラクト (インターフェイス) と POLLINGSTMT 操作のサポート クラスを作成します。

これらのツールのいずれかを使用して Oracle データベースに接続し、POLLINGSTMT 操作のサービス コントラクトを生成する場合:

  • PollingStatement バインド プロパティを指定する必要があります。 アダプターは、このバインディング プロパティの SELECT ステートメントを使用して、POLLINGSTMT 操作によって返される厳密に型指定された結果セットの正しいメタデータを生成します。

  • 必要に応じて、接続 URI に PollingId パラメーターを指定できます。 アダプターはこのパラメーターを使用して、POLLINGSTMT 操作の名前空間を生成します。

    次の例で以下を実行します。

  • PollingStatement が "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE" に設定されています。

  • PollingId が "AcctActivity" に設定されています。

WCF サービス コントラクト (インターフェイス)

次のコードは、POLLINGSTMT 操作用に生成された WCF サービス コントラクト (インターフェイス) を示しています。

[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.ServiceContractAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03", ConfigurationName="POLLINGSTMT_OperationGroup")]  
public interface POLLINGSTMT_OperationGroup {  
  
    // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)  
    // of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)  
    [System.ServiceModel.OperationContractAttribute(IsOneWay=true, Action="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMT")]  
    void POLLINGSTMT(POLLINGSTMT request);  
}  

メッセージ コントラクト

メッセージ コントラクト名前空間は、接続 URI の PollingId パラメーターによって変更されます。 要求メッセージは、厳密に型指定されたレコードのセットを返します。

[System.Diagnostics.DebuggerStepThroughAttribute()]  
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]  
[System.ServiceModel.MessageContractAttribute(WrapperName="POLLINGSTMT", WrapperNamespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", IsWrapped=true)]  
public partial class POLLINGSTMT {  
  
    [System.ServiceModel.MessageBodyMemberAttribute(Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity", Order=0)]  
    public microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD;  
  
    public POLLINGSTMT() {  
    }  
  
    public POLLINGSTMT(microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity.POLLINGSTMTRECORD[] POLLINGSTMTRECORD) {  
        this.POLLINGSTMTRECORD = POLLINGSTMTRECORD;  
    }  
}  

データ コントラクト名前空間

データ コントラクトは、サービスとクライアントの間の正式な取り決めであり、交換されるデータが抽象的に記述されています。 つまり、通信するために、クライアントとサービスは同じ型を共有する必要はなく、同じデータ コントラクトのみを共有する必要があります。

データ変更メッセージの場合、データ コントラクト名前空間も、接続 URI の PollingId パラメーター (指定されている場合) によって変更されます。 データ コントラクトは、クエリ結果セット内の厳密に型指定されたレコードを表すクラスで構成されます。 この例では、クラス定義の詳細を省略します。 クラスには、結果セット内の列を表すプロパティが含まれています。

次の例では、PollingId "AcctActivity" が使用されています。

namespace microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity {  
    using System.Runtime.Serialization;  
  
    [System.Diagnostics.DebuggerStepThroughAttribute()]  
    [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]  
    [System.Runtime.Serialization.DataContractAttribute(Name="POLLINGSTMTRECORD", Namespace="http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity")]  
    public partial class POLLINGSTMTRECORD : object, System.Runtime.Serialization.IExtensibleDataObject {…}  
     }  
}  

WCF サービス クラス

アダプター サービス参照の追加プラグインは、サービス コントラクト (インターフェイス) から実装された WCF サービス クラスのスタブを持つファイルも生成します。 ファイルの名前は OracleDBBindingService.cs です。 ロジックを挿入して、POLLINGSTMT 操作をこのクラスに直接処理できます。 svcutil.exe を使用してサービス コントラクト インターフェイスを生成する場合は、このクラスを自分で実装する必要があります。 次のコードは、アダプター サービス参照プラグインの追加によって生成された WCF サービス クラスを示しています。

namespace OracleDBBindingNamespace {  
  
    public class OracleDBBindingService : POLLINGSTMT_OperationGroup {  
  
        // CODEGEN: Generating message contract since the wrapper namespace (http://Microsoft.LobServices.OracleDB/2007/03/POLLINGSTMTAcctActivity)   
        // of message POLLINGSTMT does not match the default value (http://Microsoft.LobServices.OracleDB/2007/03)  
        public virtual void POLLINGSTMT(POLLINGSTMT request) {  
            throw new System.NotImplementedException("The method or operation is not implemented.");  
        }  
    }  
}  

POLLINGSTMT 操作の受信

Oracle Database アダプターからポーリング データを受信するには

  1. アダプター サービス参照プラグインの追加または svcutil.exe を使用して、POLLINGSTMT 操作の WCF サービス コントラクト (インターフェイス) とヘルパー クラスを生成します。 詳細については、「 Oracle Database ソリューション成果物の WCF クライアントまたは WCF サービス コントラクトを生成する」を参照してください。 アダプターに接続するときは、少なくとも PollingStatement バインド プロパティを設定する必要があります。 必要に応じて、接続 URI に PollingId パラメーターを指定できます。 アダプター サービス参照の追加プラグインを使用している場合は、構成に必要なすべてのバインド パラメーターを設定する必要があります。 これにより、生成された構成ファイルに正しく設定されます。

  2. 手順 1 で生成されたインターフェイス クラスとヘルパー クラスから WCF サービスを実装します。 POLLINGSTMT 操作から受信したデータの処理でエラーが発生した場合、このクラスの POLLINGSTMT メソッドは例外をスローしてポーリング トランザクションを中止できます。それ以外の場合、メソッドは何も返しません。 WCF サービス クラスを次のように属性化する必要があります。

    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
    
    1. アダプター サービス参照プラグインを使用してインターフェイスを生成した場合は、生成された OracleDBBindingService クラスの POLLINGSTMT メソッドにロジックを直接実装できます。 このクラスは OracleDBBindingService.cs にあります。 この例のこのコードは、 OracleDBBindingService クラスを サブクラスします。

      [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
      
      public class PollingStmtService : OracleDBBindingService  
      {  
          public override void POLLINGSTMT(POLLINGSTMT request)  
          {  
              Console.WriteLine("\nNew Polling Records Received");  
              Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
              for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)  
              {  
                  Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,  
                                      request.POLLINGSTMTRECORD[i].ACCOUNT,  
                                      request.POLLINGSTMTRECORD[i].AMOUNT,  
                                      request.POLLINGSTMTRECORD[i].TRANSDATE,  
                                      request.POLLINGSTMTRECORD[i].DESCRIPTION);  
              }  
          }  
      }  
      
    2. svcutil.exe を使用してインターフェイスを生成した場合は、インターフェイスを実装し、このクラスの POLLINGSTMT メソッドにロジックを実装する WCF サービスを作成する必要があります。

  3. 手順 2 で作成した WCF サービスのインスタンスを作成します。

    // create service instance  
    PollingStmtService pollingInstance = new PollingStmtService();  
    
  4. WCF サービスとベース接続 URI を使用して 、System.ServiceModel.ServiceHost のインスタンスを作成します。 基本接続 URI に userinfoparams またはquery_stringを含めることはできません。

    // Enable service host  
    Uri[] baseUri = new Uri[] { new Uri("oracledb://Adapter") };  
    ServiceHost srvHost = new ServiceHost(pollingInstance, baseUri);  
    
  5. OracleDBBinding を作成し、そのバインド プロパティを設定してポーリング操作を構成します。 これは、コード内で明示的に行うか、構成で宣言的に行うことができます。 少なくとも、ポーリング ステートメントとポーリング間隔を指定する必要があります。 この例では、URI の一部として資格情報を指定するので、 AcceptCredentialsInUritrue に設定する必要があります。

    // Create and configure a binding for the service endpoint. NOTE: binding  
    // parameters are set here for clarity, but these are already set in the  
    // the generated configuration file  
    OracleDBBinding binding = new OracleDBBinding();  
    
    // The credentials are included in the connection URI, so set this property to true  
    binding.AcceptCredentialsInUri = true;  
    
    // Same as statement specified in Configure Adapter dialog box  
    binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
    binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
    
    // Be sure to set the interval long enough to complete processing before  
    // the next poll  
    binding.PollingInterval = 15;  
    // Polling is transactional; be sure to set an adequate isolation level   
    // for your environment  
    binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;  
    
  6. サービス エンドポイントをサービス ホストに追加します。 これを行うには、次の手順を実行します。

    • 手順 5 で作成したバインディングを使用します。

    • 資格情報と必要に応じて PollingId を含む接続 URI を指定します。

    • コントラクトを "POLLINGSTMT_OperationGroup" として指定します。

    // Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract  
    Uri serviceUri = new Uri("oracledb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");  
    srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);  
    
  7. ポーリング データを受信するには、サービス ホストを開きます。 アダプターは、クエリが結果セットを返すたびにデータを返します。

    // Open the service host to begin polling  
    srvHost.Open();  
    
  8. ポーリングを終了するには、サービス ホストを閉じます。

    重要

    アダプターは、サービス ホストが閉じられるまでポーリングを続行します。

    srvHost.Close();  
    

次の例は、/SCOTT/ACCOUNTACTIVITY テーブルに対して実行されるポーリング クエリを示しています。 ポーリング後ステートメントは、処理されたレコードを別のテーブル /SCOTT/ACCOUNTHISTORY に移動する Oracle 関数を呼び出します。 POLLINGSTMT 操作の名前空間は、接続 URI で PollingId パラメーターを "AccountActivity" に設定することで変更されます。 この例では、生成された OracleDBBindingService クラスをサブクラス化して、POLLINGSTMT 操作の WCF サービスを作成します。ただし、生成されたクラスにロジックを直接実装できます。

using System;  
using System.Collections.Generic;  
using System.Text;  
  
// Add these three references to use the Oracle adapter  
using System.ServiceModel;  
using Microsoft.ServiceModel.Channels;  
using Microsoft.Adapters.OracleDB;  
  
using microsoft.lobservices.oracledb._2007._03.POLLINGSTMTAcctActivity;  
using OracleDBBindingNamespace;  
  
namespace OraclePollingSM  
{  
    [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]  
  
    public class PollingStmtService : OracleDBBindingService  
    {  
        public override void POLLINGSTMT(POLLINGSTMT request)  
        {  
            Console.WriteLine("\nNew Polling Records Received");  
            Console.WriteLine("Tx Id\tAccount\tAmount\tDate\t\t\tDescription");  
            for (int i = 0; i < request.POLLINGSTMTRECORD.Length; i++)  
            {  
                Console.WriteLine("{0}\t{1}\t{2}\t{3}\t{4}", request.POLLINGSTMTRECORD[i].TID,  
                                    request.POLLINGSTMTRECORD[i].ACCOUNT,  
                                    request.POLLINGSTMTRECORD[i].AMOUNT,  
                                    request.POLLINGSTMTRECORD[i].TRANSDATE,  
                                    request.POLLINGSTMTRECORD[i].DESCRIPTION);  
  
            }  
            Console.WriteLine("\nHit <RETURN> to stop polling");  
         }  
    }  
  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            ServiceHost srvHost = null;  
  
            // This URI is used to specify the address for the ServiceEndpoint  
            // It must contain credentials and the PollingId (if any) that was used to generate  
            // the WCF service callback interface  
            Uri serviceUri = new Uri("OracleDb://User=SCOTT;Password=TIGER@Adapter?PollingId=AcctActivity");  
  
            // This URI is used to initialize the ServiceHost. It cannot contain  
            // userinfoparms (credentials) or a query_string (PollingId); otherwise,  
            // an exception is thrown when the ServiceHost is initialized.  
            Uri[] baseUri = new Uri[] { new Uri("OracleDb://Adapter") };  
  
            Console.WriteLine("Sample started, initializing service host -- please wait");  
  
            // create an instanc of the WCF service callback class  
            PollingStmtService pollingInstance = new PollingStmtService();  
  
            try  
            {  
                // Create a ServiceHost with the service callback instance and a base URI (address)  
                srvHost = new ServiceHost(pollingInstance, baseUri);  
  
                // Create and configure a binding for the service endpoint. Note: binding  
                // parameters are set here for clarity but these are already set in the  
                // generated configuration file  
                //  
                // The following properties are set  
                //    AcceptCredentialsInUri (true) to enable credentials in the connection URI for AddServiceEndpoint  
                //    PollingStatement  
                //    PostPollStatement calls PROCESS_ACTIVITY on Oracle. This procedure moves the queried records to  
                //                      the ACCOUNTHISTORY table  
                //    PollingInterval (15 seconds)  
                //    TransactionIsolationLevel   
  
                OracleDBBinding binding = new OracleDBBinding();  
  
                // The Credentials are included in the Connection Uri so set this property true  
                binding.AcceptCredentialsInUri = true;  
  
                // Same as statement specified in Configure Adapter dialog box  
                binding.InboundOperationType = InboundOperation.Polling;  
                binding.PollingStatement = "SELECT * FROM ACCOUNTACTIVITY FOR UPDATE";  
                binding.PostPollStatement = "BEGIN ACCOUNT_PKG.PROCESS_ACTIVITY(); END;";  
  
                // Be sure to set the interval long enough to complete processing before  
                // the next poll  
                binding.PollingInterval = 15;  
  
                // Polling is transactional, be sure to set an adequate isolation level   
                // for your environment  
                binding.TransactionIsolationLevel = TransactionIsolationLevel.ReadCommitted;  
  
                // Add service endpoint: be sure to specify POLLINGSTMT_OperationGroup as the contract  
                srvHost.AddServiceEndpoint("POLLINGSTMT_OperationGroup", binding, serviceUri);  
  
                Console.WriteLine("Opening the service host");  
                // Open the service host to begin polling  
                srvHost.Open();  
  
                // Wait to receive request  
                Console.WriteLine("\nPolling started. Returned records will be written to the console.");  
                Console.WriteLine("Hit <RETURN> to stop polling");  
                Console.ReadLine();  
            }  
            catch (Exception e)  
            {  
                Console.WriteLine("Exception :" + e.Message);  
                Console.ReadLine();  
  
                /* If there is an Oracle Error it will be specified in the inner exception */  
                if (e.InnerException != null)  
                {  
                    Console.WriteLine("InnerException: " + e.InnerException.Message);  
                    Console.ReadLine();  
                }  
            }  
            finally  
            {  
                // IMPORTANT: you must close the ServiceHost to stop polling  
                if (srvHost.State == CommunicationState.Opened)  
                    srvHost.Close();  
                else  
                    srvHost.Abort();  
            }  
  
        }  
    }  
}  

参照

WCF サービス モデルを使用して Oracle Database アプリケーションを開発する