다음을 통해 공유


WCF 채널 모델을 사용하여 Oracle 데이터베이스 LOB 데이터 형식 스트리밍

Oracle Database용 Microsoft BizTalk 어댑터는 특정 작업에 대한 LOB 데이터의 엔드투엔드 스트리밍을 지원합니다. 이 항목의 섹션에서는 WCF 채널 모델을 사용할 때 LOB 데이터에 대한 스트리밍을 구현하는 방법을 설명합니다.

어댑터가 LOB 데이터 형식의 스트리밍을 지원하는 방법에 대한 배경 정보는 Oracle Database 어댑터에서 큰 개체 데이터 형식 스트리밍을 참조하세요. 계속하기 전에 이 항목을 읽어야 합니다.

LOB 데이터 스트리밍을 보여 주는 샘플은 Oracle 데이터베이스 어댑터에 포함된 SDK 샘플에서 사용할 수 있습니다. 자세한 내용은 SDK의 샘플을 참조하세요.

어댑터로 아웃바운드 메시지 스트리밍

어댑터는 UpdateLOB 작업에 대한 요청 메시지에 대한 엔드 투 엔드 LOB 데이터 스트리밍을 지원합니다.

WCF 채널 모델의 UpdateLOB 작업에서 엔드 투 엔드 스트리밍을 지원하려면 다음을 수행해야 합니다.

  1. UseAmbientTransaction 바인딩 속성을 true로 설정합니다.

  2. LOB 데이터를 스트리밍할 수 있는 System.ServiceModel.Channels.BodyWriter 를 구현합니다(LOB 데이터에서 노드 값 스트리밍 수행).

  3. 트랜잭션 scope 내에서 UpdateLOB 작업을 수행합니다.

  4. Message.Create 메서드의 적절한 오버로드를 사용하여 메시지 본문에 이 BodyWriter를 제공하여 작업을 호출하는 데 사용되는 System.ServiceModel.Message만듭니다.

UseAmbientTransaction 바인딩 속성 설정

다음 예제에서는 Oracle 데이터베이스 어댑터에 대한 바인딩을 만들고 UseAmbientTransaction 바인딩 속성을 설정하는 방법을 보여 줍니다.

// Create binding  
OracleDBBinding odbBinding = new OracleDBBinding();  
  
//set the binding property  
binding.UseAmbientTransaction = true;  
  

BodyWriter 구현

다음 예제에서는 노드 값 스트리밍을 수행하는 BodyWriter 의 구현을 보여 줍니다.

/// <summary>  
/// This class overrides the OnWriteBodyContents function to do node-value streaming  
/// </summary>  
class StreamingBodyWriter : BodyWriter, IDisposable  
{  
    XmlReader m_reader = null;  
  
    int m_chunkSize;  
    /// <summary>  
    /// Initializes the body writer  
    /// </summary>  
    /// <param name="reader">Reader for input</param>  
    /// <param name="chunkSize">The chunksize in which the data is passed to adapter</param>  
    public StreamingBodyWriter(XmlReader reader, int chunkSize)  
        : base(false)  
    {  
        m_reader = reader;  
        if (chunkSize \<= 0)  
            throw new ApplicationException("ChunkSize should be a positive value");  
        m_chunkSize = chunkSize;  
    }  
  
    protected override void OnWriteBodyContents(XmlDictionaryWriter writer)  
    {  
        if (m_reader == null)  
            throw new ApplicationException("Reader cannot be null");  
  
        while (m_reader.Read())  
        {  
            switch (m_reader.NodeType)  
            {  
                case XmlNodeType.Element:  
                    writer.WriteStartElement(m_reader.LocalName, m_reader.NamespaceURI);  
                    break;  
                case XmlNodeType.Text:  
                    #region Streaming Code  
                    char[] tempBuffer = new char[m_chunkSize];  
                    int length = 0;  
                    while ((length = m_reader.ReadValueChunk(tempBuffer, 0, m_chunkSize)) > 0)  
                    {  
                        writer.WriteString(new String(tempBuffer, 0, length));  
                    }  
                    #endregion  
                    break;  
                case XmlNodeType.EndElement:  
                    writer.WriteEndElement();  
                    break;  
            }  
        }  
  
    }  
  
    #region IDisposable Members  
  
    public void Dispose()  
    {  
        if (m_reader != null)  
        {  
            m_reader.Close();  
            m_reader = null;  
        }  
    }  
  
    #endregion  
}  

트랜잭션 범위 내에서 작업 수행

다음 예제에서는 트랜잭션 scope 내에서 작업을 수행하는 방법을 보여 줍니다.

// Create a transaction scope  
using(TransactionScope tx = new TransactionScope())  
{  
  // perform operations within the transaction  
  // ...  
  // ...  
  
  //Complete the transaction  
  tx.Complete()  
}  
  

BodyWriter를 사용하여 메시지 만들기

다음 예제에서는 앞의 예제에서 BodyWriter 를 사용하여 UpdateLOB 요청 메시지를 만드는 방법을 보여 줍니다. 메시지 데이터는 파일에서 읽습니다.

// Create a transaction scope  
using(TransactionScope tx = new TransactionScope())  
{  
    XmlReader readerIn = XmlReader.Create ("updatelob.xml");  
    // StreamingBodyWrtier class is responsible for streaming  
    StreamingBodyWriter stBW = new StreamingBodyWriter(readerIn, chunkSize);  
  
    Message InputMsg = Message.CreateMessage(MessageVersion.Default,  
    "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER/UpdateLOB",   
    stBW);  
  
    //Send the request message and get the output message  
    OutputMsg = channel.Request(InputMsg);  
  
    tx.Complete();  
}  
  

어댑터에서 인바운드 메시지 스트리밍

어댑터는 다음 인바운드 메시지에 대한 엔드 투 엔드 LOB 데이터 스트리밍을 지원합니다.

  • LOB 데이터를 포함하는 OUT 또는 IN OUT 매개 변수가 있는 함수에 대한 응답 메시지입니다. RECORD TYPE 매개 변수에는 LOB 데이터 열이 포함될 수 있습니다.

  • LOB 데이터를 포함하는 OUT REF CURSOR 매개 변수(또는 반환 값)가 있는 함수에 대한 응답 메시지입니다. 여기에는 IN OUT REF CURSOR 매개 변수의 출력 쪽이 포함됩니다.

  • LOB 데이터를 포함하는 IN 또는 IN OUT 매개 변수가 있는 프로시저에 대한 응답 메시지입니다. RECORD TYPE 매개 변수에는 LOB 데이터 열이 포함될 수 있습니다.

  • LOB 데이터를 포함하는 OUT REF CURSOR 매개 변수가 있는 프로시저에 대한 응답 메시지입니다. 여기에는 IN OUT REF CURSOR 매개 변수의 출력 쪽이 포함됩니다.

  • LOB 데이터가 포함된 결과 집합을 반환하는 SQLEXECUTE 작업에 대한 응답 메시지입니다.

  • 테이블 또는 뷰에 대한 응답 메시지 결과 집합에서 LOB 데이터를 반환하는 작업 선택을 선택합니다.

  • (인바운드) POLLINGSTMT 작업에 대한 요청 메시지

    WCF 채널 모델의 인바운드 메시지에서 엔드 투 엔드 스트리밍을 지원하려면 다음을 수행해야 합니다.

  1. System.Xml 구현 합니다. LOB 데이터를 스트리밍할 수 있는 XmlDictionaryWriter 입니다(LOB 데이터에서 노드-값 스트리밍 수행).

  2. XmlDictionaryWriter를 사용하여 WriteBodyContents 메서드를 호출하여 Message를 사용합니다.

XmlDictionaryWriter 구현

다음 예제에서는 노드 값 스트리밍을 수행하는 XmlDictionaryWriter 의 구현을 보여 줍니다.

using System;  
using System.Xml;  
using System.Text;  
  
class FileXmlWriter : XmlDictionaryWriter  
{  
    XmlTextWriter xts;  
  
    public FileXmlWriter(string file)  
    {  
        xts = new XmlTextWriter(file, Encoding.UTF8);  
    }  
  
    public override void WriteBase64(byte[] buffer, int index, int count)  
    {  
        xts.WriteBase64(buffer, index, count);  
    }  
  
    public override void WriteCData(string text)  
    {  
        xts.WriteCData(text);  
    }  
  
    public override void WriteCharEntity(char ch)  
    {  
        xts.WriteCharEntity(ch);  
    }  
  
    public override void WriteChars(char[] buffer, int index, int count)  
    {  
        xts.WriteChars(buffer, index, count);  
    }  
  
    public override void WriteComment(string text)  
    {  
        xts.WriteComment(text);  
    }  
  
    public override void WriteDocType(string name, string pubid, string sysid, string subset)  
    {  
        xts.WriteDocType(name, pubid, sysid, subset);  
    }  
  
    public override void WriteEndAttribute()  
    {  
        xts.WriteEndAttribute();  
    }  
  
    public override void WriteEndDocument()  
    {  
        xts.WriteEndDocument();  
    }  
  
    public override void WriteEndElement()  
    {  
        xts.WriteEndElement();  
    }  
  
    public override void WriteEntityRef(string name)  
    {  
        xts.WriteEntityRef(name);  
    }  
  
    public override void WriteFullEndElement()  
    {  
        xts.WriteFullEndElement();  
    }  
  
    public override void WriteProcessingInstruction(string name, string text)  
    {  
        xts.WriteProcessingInstruction(name, text);  
    }  
  
    public override void WriteRaw(string data)  
    {  
        xts.WriteRaw(data);  
    }  
  
    public override void WriteRaw(char[] buffer, int index, int count)  
    {  
        xts.WriteRaw(buffer, index, count);  
    }  
  
    public override void WriteStartAttribute(string prefix, string localName, string ns)  
    {  
        xts.WriteStartAttribute(prefix, localName, ns);  
    }  
  
    public override void WriteStartDocument(bool standalone)  
    {  
        xts.WriteStartDocument(standalone);  
    }  
  
    public override void WriteStartDocument()  
    {  
        xts.WriteStartDocument();  
    }  
  
    public override void WriteStartElement(string prefix, string localName, string ns)  
    {  
        xts.WriteStartElement(localName);  
    }  
  
    public override void WriteString(string text)  
    {  
        xts.WriteString(text);  
    }  
  
    public override void WriteSurrogateCharEntity(char lowChar, char highChar)  
    {  
        xts.WriteSurrogateCharEntity(lowChar, highChar);  
    }  
  
    public override void WriteWhitespace(string ws)  
    {  
        xts.WriteWhitespace(ws);  
    }  
  
    public override void Close()  
    {  
        xts.Close();  
    }  
  
    public override void Flush()  
    {  
        xts.Flush();  
    }  
  
    public override string LookupPrefix(string ns)  
    {  
        return xts.LookupPrefix(ns);  
    }  
  
    public override WriteState WriteState  
    {  
        get { return xts.WriteState; }  
    }  
  
}  

XmlDictionaryWriter를 사용하여 메시지 사용

다음 예제에서는 앞의 예제에서 구현된 FileXmlWriter 를 사용하여 응답 메시지 선택 테이블을 사용하는 방법을 보여줍니다. ( FileWriter 클래스는 하위 클래스 XmlDictionaryWriter에 의해 만들어졌습니다.) 이 예제에서는 IRequestChannel 채널을 사용하여 선택 작업을 호출합니다. 채널 만들기의 세부 정보를 생략했습니다. 요청 선택 메시지가 파일에서 읽혀지고 응답 선택 메시지가 파일에 기록됩니다.

// Read Select message body from a file  
XmlReader readerIn = XmlReader.Create("select.xml");  
Message InputMsg = Message.CreateMessage(MessageVersion.Default,  
    "http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER/Select", readerIn);  
  
Message OutputMsg = channel.Request(InputMsg);  
  
// Streaming response message to select_output.xml using the custom XmlDictionaryWriter;  
FileXmlWriter fileXmlWriter = new FileXmlWriter("select_output.xml");  
OutputMsg.WriteBodyContents(fileXmlWriter);  
fileXmlWriter.Flush();  
fileXmlWriter.Close();  
  
// Streaming complete close output message;  
OutputMsg.Close();  

다음 XML은 선택 작업에 대한 요청 메시지(select.xml 파일의 내용)를 보여 줍니다. CUSTOMER 테이블에는 PHOTO라는 BLOB 열이 포함되어 있습니다.

<Select xmlns="http://Microsoft.LobServices.OracleDB/2007/03/SCOTT/Table/CUSTOMER">  
  <COLUMN_NAMES>*</COLUMN_NAMES>  
  <FILTER>NAME='Kim Ralls'</FILTER>  
</Select>  

참고 항목

WCF 채널 모델을 사용하여 Oracle Database 애플리케이션 개발