WCF 서비스 모델을 사용하여 Oracle Database에서 폴링 기반 데이터 변경 메시지 받기
Oracle 테이블 또는 뷰에 대해 폴링 기반 데이터 변경 메시지를 받도록 Oracle Database용 Microsoft BizTalk 어댑터를 구성할 수 있습니다. 데이터 변경 메시지를 수신하기 위해 어댑터는 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 서비스를 호스트합니다.
이 섹션의 topics 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)를 사용하여 POLLINGSTMT 작업에 대한 WCF 서비스 계약(인터페이스) 및 지원 클래스를 만듭니다.
다음 도구 중 하나를 사용하여 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 데이터베이스 어댑터에서 폴링 데이터를 받으려면
어댑터 서비스 참조 플러그 인 추가 또는 svcutil.exe 사용하여 POLLINGSTMT 작업에 대한 WCF 서비스 계약(인터페이스) 및 도우미 클래스를 생성합니다. 자세한 내용은 Oracle Database 솔루션 아티팩트용 WCF 클라이언트 또는 WCF 서비스 계약 생성을 참조하세요. 최소한 어댑터에 연결할 때 PollingStatement 바인딩 속성을 설정해야 합니다. 선택적으로 연결 URI에서 PollingId 매개 변수를 지정할 수 있습니다. 어댑터 서비스 참조 플러그 인 추가를 사용하는 경우 구성에 필요한 모든 바인딩 매개 변수를 설정해야 합니다. 이렇게 하면 생성된 구성 파일에서 올바르게 설정됩니다.
1단계에서 생성된 인터페이스 및 도우미 클래스에서 WCF 서비스를 구현합니다. 이 클래스의 POLLINGSTMT 메서드는 POLLINGSTMT 작업에서 받은 데이터를 처리하는 동안 오류가 발생하면 폴링 트랜잭션을 중단하는 예외를 throw할 수 있습니다. 그렇지 않으면 메서드는 아무것도 반환하지 않습니다. 다음과 같이 WCF 서비스 클래스의 특성을 지정해야 합니다.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
어댑터 서비스 참조 플러그 인 추가를 사용하여 인터페이스를 생성한 경우 생성된 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); } } }
svcutil.exe 사용하여 인터페이스를 생성한 경우 인터페이스를 구현하는 WCF 서비스를 만들고 이 클래스의 POLLINGSTMT 메서드에서 논리를 구현해야 합니다.
2단계에서 만든 WCF 서비스의 instance 만듭니다.
// create service instance PollingStmtService pollingInstance = new PollingStmtService();
WCF 서비스 및 기본 연결 URI를 사용하여 System.ServiceModel.ServiceHost의 instance 만듭니다. 기본 연결 URI에는 userinfoparams 또는 query_string 포함될 수 없습니다.
// Enable service host Uri[] baseUri = new Uri[] { new Uri("oracledb://Adapter") }; ServiceHost srvHost = new ServiceHost(pollingInstance, baseUri);
OracleDBBinding을 만들고 바인딩 속성을 설정하여 폴링 작업을 구성합니다. 코드에서 명시적으로 또는 구성에서 선언적으로 이 작업을 수행할 수 있습니다. 최소한 폴링 문과 폴링 간격을 지정해야 합니다. 이 예제에서는 자격 증명을 URI의 일부로 지정하므로 AcceptCredentialsInUri 도 true로 설정해야 합니다.
// 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;
서비스 호스트에 서비스 엔드포인트를 추가합니다. 가상 하드 디스크 파일에 대한 중요 정보를 제공하려면
5단계에서 만든 바인딩을 사용합니다.
자격 증명을 포함하는 연결 URI를 지정하고 필요한 경우 PollingId를 지정합니다.
계약을 "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);
폴링 데이터를 받으려면 서비스 호스트를 엽니다. 어댑터는 쿼리가 결과 집합을 반환할 때마다 데이터를 반환합니다.
// Open the service host to begin polling srvHost.Open();
폴링을 종료하려면 서비스 호스트를 닫습니다.
중요
어댑터는 서비스 호스트가 닫을 때까지 계속 폴링됩니다.
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();
}
}
}
}