수신 처리를 위한 메시지 일괄 처리
일괄 처리 콜백
수신 어댑터에서 메시징 엔진으로 전송된 일괄 처리는 비동기적으로 처리됩니다. 따라서 어댑터는 콜백을 어댑터의 특정 상태에 연결하여 성공 또는 실패에 대한 알림을 받고 필요한 정리 작업을 수행할 수 있도록 하는 메커니즘을 필요로 합니다. 콜백 의미는 유연하기 때문에 어댑터가 다음과 같은 접근 방식을 하나만 사용하거나 세 가지 모두를 결합하여 이러한 방법은 다음과 같습니다.
모든 콜백은 IBTBatchCallBack을 구현하는 동일한 개체 instance 만들어집니다.
새 일괄 처리를 요청할 때 엔진에 전달된 쿠키는 콜백을 어댑터의 상태와 연관시키는 데 사용됩니다.
IBTBatchCallBack을 구현하는 각 일괄 처리에 대해 다른 콜백 개체가 있습니다. 여기서 개체의 상태는 각각 고유합니다.
일괄 처리가 처리되면 어댑터가 IBTBatchCallBack.BatchComplete 구현 시 다시 호출됩니다. 일괄 처리의 전체 상태는 첫 번째 매개 변수인 HRESULT 상태로 표시됩니다. 이 값이 0보다 크거나 같으면 엔진이 데이터를 소유하게 되었으며 어댑터가 네트워크에서 해당 데이터를 삭제할 수 있으므로 일괄 처리에 성공한 것입니다. 음수 상태 일괄 처리가 실패했음을 나타냅니다. 일괄 처리의 작업이 성공하지 못했으며 어댑터가 오류를 처리해야 합니다.
일괄 처리가 실패한 경우 어댑터는 작업에서 실패한 항목을 파악해야 합니다. 예를 들어 어댑터가 디스크에서 20개 파일을 읽고 단일 일괄 처리를 사용하여 BizTalk Server 제출했다고 가정합니다. 열 번째 파일이 손상된 경우 어댑터는 해당 파일을 일시 중단하고 나머지 19 파일을 다시 제출해야 합니다. 이 정보는 BTBatchOperationStatus[]형식인 short 및 형식의 두 번째 및
operationStatus
세 번째 매개 변수opCount
(작업 수)의 어댑터에서 사용할 수 있습니다.
참고
단일 일괄 처리 개체에 대해 메시지를 두 번 이상 전송하지 마십시오. 동일한 일괄 처리에 대해 동일한 메시지 개체를 두 번 이상 전송하면 엔진 오류가 발생합니다.
작업 수는 일괄 처리에 있는 작업 유형( BTBatchOperationStatus 배열의 크기)을 나타냅니다. 작업 상태 배열의 각 요소는 지정된 작업 유형에 해당합니다. BTBatchOperationStatus 배열을 사용하면 어댑터는 실패를 나타내는 음의 HRESULT 값에 대해 BTBatchOperationStatus.MessageStatus 배열을 확인하여 지정된 작업의 어떤 항목이 실패했는지 확인할 수 있습니다. 위의 시나리오에서 어댑터는 19개의 메시지를 전송하고 1개의 메시지는 일시 중단하는 새 일괄 처리를 만듭니다.
다음 코드 조각은 어댑터가 엔진에서 전송 프록시를 통해 새 일괄 처리를 요청하고 쿠키 방식을 사용하여 엔진에 단일 메시지를 전송하는 방식을 보여 줍니다. 메시징 엔진은 제출된 메시지의 전체 일괄 처리 처리를 완료했을 때 BatchComplete 메서드를 일괄 처리 콜백으로 호출합니다.
using Microsoft.BizTalk.TransportProxy.Interop;
using Microsoft.BizTalk.Message.Interop;
public class MyAdapter :
IBTTransport,
IBTTransportConfig,
IBTTransportControl,
IPersistPropertyBag,
IBaseComponent,
IBTBatchCallBack
{
private IBTTransportProxy _tp;
public void BatchComplete(
Int32 status,
Int16 opCount,
BTBatchOperationStatus[] operationStatus,
System.Object callbackCookie)
{
// Use cookie to correlate callback with work done,
// in this example the batch is to submit a single
// file the name of which will be in the
// callbackCookie
string fileName = (string)callbackCookie;
if ( status >= 0 )
// DeleteFile from disc
File.Delete(fileName);
else
// Rename file to fileName.bad
File.Move(fileName, fileName + ".bad");
}
private void SubmitMessage(
IBaseMessage msg,
string fileName)
{
// Note: Pass in the filename as the cookie
IBTTransportBatch batch =
_tp.GetBatch(this, (object)fileName);
// Add msg to batch for submitting
batch.SubmitMessage(msg);
// Process this batch
batch.Done(null);
}
}
BizTalk Server SDK에는 파일, HTTP, MSMQ 및 트랜잭션 어댑터와 같은 어댑터에 대한 샘플이 포함되어 있습니다. 이러한 어댑터는 모두 BaseAdapter라는 공통된 빌딩 블록을 기반으로 합니다. BaseAdapter 버전 1.0.1은 작업 상태의 구문을 분석하고 전송할 일괄 처리를 새로 다시 빌드하는 관련 코드를 모두 포함합니다.
경합 상태
오류를 해결하고 전송된 일괄 처리의 최종 결과를 판단하는 두 가지 작업은 매우 단순하지만 서로 다른 스레드의 정보에 의존합니다.
어댑터는 어댑터의 BatchComplete 콜백 메서드에 BizTalk Server 전달된 정보에 따라 오류를 처리합니다. 이 콜백은 어댑터의 스레드에서 실행됩니다.
DTCCommitConfirm 은 IBTDTCCommitConfirm 개체의 메서드입니다. IBTDTCCommitConfirm 개체의 instance 일괄 처리 IBTTransportBatch::D one 호출에 의해 반환됩니다. 이 instance 어댑터의 콜백 스레드와 다른 IBTTTransportBatch::D one 호출과 동일한 스레드에 있습니다.
어댑터가 IBTTTransportBatch::D 를 호출할 때마다 메시징 엔진은 별도의 스레드에서 BatchComplete 콜백 메서드를 호출하여 일괄 처리 제출 결과를 보고합니다. BatchComplete에서 어댑터는 일괄 처리 통과 또는 실패 여부에 따라 트랜잭션을 커밋하거나 롤백해야 합니다. 두 경우 모두 어댑터는 DTCCommitConfirm을 호출하여 트랜잭션의 상태 보고해야 합니다.
어댑터의 BatchComplete 구현에서 BatchComplete가 실행할 때 IBTTTransportBatch::D one에서 반환된 IBTDTCCommitConfirm 개체를 항상 사용할 수 있다고 가정할 수 있기 때문에 가능한 경합 조건이 존재합니다. 그러나 BatchComplete 는 IBTTTransportBatch::D one 이 반환되기 전에 별도의 메시징 엔진 스레드에서 호출할 수 있습니다. 어댑터가 BatchComplete 구현의 일부로 IBTDTCCommitConfirm 개체에 액세스하려고 하면 호출 스레드가 더 이상 존재하지 않으므로 액세스 위반이 발생할 수 있습니다. 다음 솔루션을 사용하여 이런 상황이 발생하지 않도록 하십시오.
다음 예에서는 이벤트를 사용하여 문제를 해결합니다. 여기서는 이벤트를 사용하는 속성을 통해 인터페이스 포인터에 액세스합니다. get은 항상 처리 전에 set이 완료되기를 기다립니다.
protected IBTDTCCommitConfirm CommitConfirm
{
set
{
this.commitConfirm = value;
this.commitConfirmEvent.Set();
}
get
{
this.commitConfirmEvent.WaitOne();
return this.commitConfirm;
}
}
protected IBTDTCCommitConfirm commitConfirm = null;
private ManualResetEvent commitConfirmEvent = new ManualResetEvent(false);
일괄 처리 상태 코드
전체 일괄 처리 상태 코드는 일괄 처리의 결과를 나타냅니다. 작업 상태는 개별 메시지 항목에 대한 전송 상태 코드를 제공합니다. 보안 관련 오류 또는 엔진 종료 시 메시지가 전송된 경우 등 여러 가지 이유로 일괄 처리에 실패할 수 있습니다. 일반적으로 엔진은 종료 시 새 작업을 받지 않지만 진행 중인 작업은 완료합니다. 다음 표는 일괄 처리 상태 또는 작업 상태로 반환되는 몇 가지 공통적인 HRESULT 값을 나타냅니다. 또한 이들 값이 성공 또는 실패 코드인지를 나타냅니다. 이러한 코드의 적절한 처리는 어댑터 오류를 처리하는 방법에 자세히 설명되어 있습니다.
코드(BTTransportProxy 클래스에 정의됨) | 성공/실패 코드 | Description |
---|---|---|
BTS_S_EPM_SECURITY_CHECK_FAILED | Success | 보안 검사를 수행하고 인증에 실패한 메시지를 삭제하도록 포트가 구성되었습니다. 어댑터는 이 상태 코드를 반환하는 일괄 처리를 일시 중단하지 말아야 합니다. |
BTS_S_EPM_MESSAGE_SUSPENDED | Success | 하나 이상의 메시지가 일시 중단되었으며 엔진이 데이터를 소유하게 되었음을 나타냅니다. 이는 메시징 엔진이 메시지 전송을 받아들인 성공 코드입니다. |
E_BTS_URL_DISALLOWED | 실패 | 잘못된 InboundTransportLocation으로 메시지가 제출되었습니다. |
Batch 작업
다음 표에서는 어댑터가 지정된 일괄 처리에 작업을 추가하는 데 사용하는 IBTTransportBatch 개체의 멤버 메서드 및 작업에 대해 자세히 설명합니다.
메서드 이름 | 작업 유형 | Description |
---|---|---|
SubmitMessage | 전송 | 메시지를 엔진에 전송합니다. |
SubmitResponseMessage | 전송 | 응답 메시지를 엔진에 전송합니다. 이는 간청-응답 쌍의 응답 메시지입니다. |
DeleteMessage | 삭제 | 어댑터가 비차단 송신을 사용하여 네트워크상에서 성공적으로 전송한 메시지를 삭제합니다. 송신 차단을 사용하는 어댑터는 어댑터가 TransmitMesssage에서 반환 true 되는 경우 메시징 엔진이 어댑터를 대신하여 삭제하므로 이 메서드를 호출할 필요가 없습니다. |
MoveToSuspendQ | MoveToSuspendQ | 메시지를 일시 중단된 큐로 이동합니다. |
Resubmit | Resubmit | 나중에 전송을 위해 메시지를 다시 시도해야 함을 요청합니다. 이는 일반적으로 전송 시도가 실패한 후 호출됩니다. |
MoveToNextTransport | MoveToNextTransport | 백업 전송을 사용하여 메시지를 전송할 것을 요청합니다. 일반적으로 모든 재시도가 끝난 후 호출됩니다. 백업 전송이 없으면 이 메서드가 실패합니다. |
SubmitRequestMessage | SubmitRequest | 요청 메시지를 전송합니다. 이는 요청-응답 쌍의 요청 메시지입니다. |
CancelRequestForResponse | CancelRequestForResponse | 어댑터가 더 이상 요청-응답 쌍의 응답 메시지를 대기하지 않음을 엔진에 알려 줍니다. |
지우기 | 해당 없음 | 일괄 처리에서 모든 작업을 지웁니다. |
완료 | 해당 없음 | 처리를 위해 메시지를 엔진에 일괄 전송합니다. |
Batch 관리
일괄 처리는 메시징 엔진에서 네이티브 코드로 구현됩니다. 이러한 이유로 해서 관리 코드로 작성된 어댑터는 일괄 처리를 완료한 후 일괄 처리에 대해 RCW(런타임 호출 가능 래퍼)를 릴리스해야 합니다. 이 작업은 Marshal.ReleaseComObject API를 사용하여 관리 코드에서 수행됩니다. 반환된 참조 수가 0에 도달할 때까지 while 반복에서 이 API가 호출되어야 합니다.
BizTalk Server 일괄 처리 내에서 메시지를 동기적으로 처리합니다. 많은 일괄 처리를 동시에 처리하면 응용 프로그램 도메인의 일괄 처리 크기를 조정하여 어댑터에서 일부 최적화 기회를 얻을 수 있습니다. 예를 들어 특정 제한에 도달할 때까지 FTP 사이트의 모든 파일을 처리할 수 있습니다. SAP의 경우 이후 일괄 처리로 전송되는 여러 메시지로 단일 스트림을 처리할 수 있습니다.
어댑터가 작업을 BizTalk Server 다시 전달하는 데 사용하는 일괄 처리는 BizTalk Server 어댑터에 제공하는 메시지 목록에 정확히 해당할 필요가 없습니다. 즉, 트랜잭션 송신을 수행할 때 다시 제출 작업 MoveToNextTransport 및 MoveToSuspendQ 를 별도의 일괄 처리로 분할해야 합니다. 대부분의 어댑터는 이후 처리를 위해 다중 엔드포인트에 대해 전송된 메시지의 일괄 처리를 개별 메시지 목록으로 분류합니다.
요점은 BizTalk Server 메시지 일괄 처리와 관련된 규칙(트랜잭션과 연결된 규칙 외에)이 없다는 것입니다. 일괄 처리는 어댑터가 BizTalk Server 들어오고 나가는 메시지를 청크하는 구현별 방법입니다.
어댑터는 BizTalk Server BizTalk Server 대한 응답을 위해 더 큰 일괄 처리로 제공된 여러 개의 작은 일괄 처리에서 메시지를 일괄 처리할 수 있습니다. 이는 매우 작은 메시지를 많이 처리하는 트랜잭션 어댑터에서 중요한 최적화로 "메시지당 총 트랜잭션 수" 비율을 최소화합니다.
일반적으로 BizTalk Server 5~10개 메시지의 송신 쪽 일괄 처리를 생성합니다. 매우 작은 메시지인 경우 어댑터는 트랜잭션 삭제 일괄 처리를 다시 BizTalk Server 제출하기 전에 최대 100개 이상의 메시지를 일괄 처리할 수 있습니다. 이와 같은 최적화는 구현하기 쉽지 않으므로 메시지가 어댑터 메모리에 머무르면서 일부 임계값에 도달할 때까지 무한정 대기하지 않도록 해야 합니다.
일괄 처리의 중요성은 MQSeries와 같은 처리량이 높은 어댑터의 BizTalk Server 성능 번호에서 확인할 수 있습니다. 이러한 어댑터에서는 메시지가 송신되는 빈도보다 최소 두 배 이상 메시지를 수신합니다. 기본적으로 수신 어댑터는 100개의 메시지 일괄 처리를 사용하고 송신 어댑터는 지정된 기본 BizTalk Server 일괄 처리를 사용합니다.
트랜잭션 일괄 처리
트랜잭션 개체를 만들고 BizTalk Server 전달하는 어댑터를 작성하는 경우 다음을 수행하는 코드를 작성할 책임이 있습니다.
트랜잭션을 커밋하거나 종료하기 위해 일괄 처리 작업의 최종 결과를 결정합니다. 이는 MSMQ(메시지 큐) 큐에 쓰기 또는 트랜잭션 데이터베이스 작업과 같이 BizTalk Server 종속되지 않은 이 트랜잭션의 scope 내의 다른 트랜잭션 분기에 따라 달라질 수 있습니다.
IBTDTCCommitConfirm.DTCCommitConfirm 메서드를 호출하여 최종 결과를 BizTalk Server 알 수 있습니다. 반환은
true
트랜잭션의 성공적인 커밋을 나타냅니다. 반환은false
트랜잭션의 실패 및 롤백을 의미합니다.어댑터는 내부 추적 데이터를 유지하려면 트랜잭션의 최종 결과에 대해 BizTalk Server 알려야 합니다. 어댑터는 DTCCommitConfirm을 호출하여 BizTalk Server 결과를 알 수 있습니다. 어댑터가 이렇게 하지 않으면 심각한 메모리 손실이 발생하고 MSDTC 트랜잭션 시간이 초과되고 작업이 성공적으로 완료되더라도 실패할 수 있습니다.