WCF 채널 모델을 사용하여 Oracle 데이터베이스 LOB 데이터 형식 스트리밍
Oracle Database용 Microsoft BizTalk 어댑터는 특정 작업에 대한 LOB 데이터의 엔드투엔드 스트리밍을 지원합니다. 이 항목의 섹션에서는 WCF 채널 모델을 사용할 때 LOB 데이터에 대한 스트리밍을 구현하는 방법을 설명합니다.
어댑터가 LOB 데이터 형식의 스트리밍을 지원하는 방법에 대한 배경 정보는 Oracle Database 어댑터에서 큰 개체 데이터 형식 스트리밍을 참조하세요. 계속하기 전에 이 항목을 읽어야 합니다.
LOB 데이터 스트리밍을 보여 주는 샘플은 Oracle 데이터베이스 어댑터에 포함된 SDK 샘플에서 사용할 수 있습니다. 자세한 내용은 SDK의 샘플을 참조하세요.
어댑터로 아웃바운드 메시지 스트리밍
어댑터는 UpdateLOB 작업에 대한 요청 메시지에 대한 엔드 투 엔드 LOB 데이터 스트리밍을 지원합니다.
WCF 채널 모델의 UpdateLOB 작업에서 엔드 투 엔드 스트리밍을 지원하려면 다음을 수행해야 합니다.
UseAmbientTransaction 바인딩 속성을 true로 설정합니다.
LOB 데이터를 스트리밍할 수 있는 System.ServiceModel.Channels.BodyWriter 를 구현합니다(LOB 데이터에서 노드 값 스트리밍 수행).
트랜잭션 scope 내에서 UpdateLOB 작업을 수행합니다.
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 채널 모델의 인바운드 메시지에서 엔드 투 엔드 스트리밍을 지원하려면 다음을 수행해야 합니다.
System.Xml 구현 합니다. LOB 데이터를 스트리밍할 수 있는 XmlDictionaryWriter 입니다(LOB 데이터에서 노드-값 스트리밍 수행).
이 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>