Freigeben über


Verarbeiten von Nachrichten für die Empfangsverarbeitung in Batches

Batchrückrufe

Batches, die von Empfangsadaptern an die Messaging-Engine übermittelt wurden, werden asynchron verarbeitet. Daher benötigt der Adapter einen Mechanismus, um einen Rückruf an einen bestimmten Status im Adapter zu binden, sodass er über Erfolg oder Misserfolg unterrichtet werden kann und die erforderlichen Bereinigungsaktionen ausführen kann. Die Rückrufsemantik ist flexibel, sodass Adapter eine einzelne oder eine Kombination aus drei Herangehensweisen verwenden können. Diese lauten wie folgt:

  • Alle Rückrufe erfolgen für dasselbe Objekt instance, das IBTBatchCallBack implementiert.

  • Das beim Anfordern eines neuen Batches an die Engine übergebene Cookie wird dazu verwendet, den Rückruf mit dem Status in den Adaptern zu korrelieren.

  • Es gibt ein anderes Rückrufobjekt für jeden Batch, der IBTBatchCallBack implementiert. Hierbei besitzt jedes Objekt seinen eigenen privaten Status.

    Wenn der Batch verarbeitet wurde, wird der Adapter für seine Implementierung von IBTBatchCallBack.BatchComplete zurückgerufen. Der allgemeine Status des Batches wird durch den ersten Parameter, den HRESULT-Status, angegeben. Ist dieser Wert größer oder gleich Null, war der Batch insofern erfolgreich, als dass die Engine die Daten besitzt und sie nun aus der Verbindung löschen kann. Ein negativer status gibt an, dass der Batch fehlgeschlagen ist: Keiner der Vorgänge im Batch war erfolgreich, und der Adapter ist für die Behandlung des Fehlers verantwortlich.

    Bei einem Batchfehler muss der Adapter wissen, welches Element in welchem Vorgang fehlgeschlagen ist. Angenommen, der Adapter liest 20 Dateien vom Datenträger und übermittelt sie mithilfe eines einzelnen Batches an BizTalk Server. Wenn die zehnte Datei beschädigt ist, muss der Adapter diese eine Datei anhalten und die übrigen 19 erneut übermitteln. Diese Informationen stehen dem Adapter im zweiten und dritten Parameter zur Verfügung–opCount (Vorgangsanzahl) vom Typ short und operationStatus, der vom Typ BTBatchOperationStatus[ist.

Hinweis

In einem einzelnen Batchobjekt sollte eine Nachricht nicht mehr als ein Mal übermittelt werden. Das mehrfache Übermitteln desselben Nachrichtenobjekts im selben Batch führt zu Engine-Fehlern.

Die Vorgangsanzahl gibt an, wie viele Arten von Vorgängen im Batch enthalten waren (die Größe des BTBatchOperationStatus-Arrays ). Jedes Element im Vorgangsstatusarray entspricht einem bestimmten Vorgangstyp. Mithilfe des BTBatchOperationStatus-Arrays kann der Adapter ermitteln, welches Element in einem bestimmten Vorgang fehlgeschlagen ist, indem er das BTBatchOperationStatus.MessageStatus-Array auf negative HRESULT-Werte untersucht, die einen Fehler darstellen. Im vorangehenden Szenario erstellt der Adapter einen neuen Batch mit 19 übermittelten Nachrichten und einer angehaltener Nachricht.

Im folgenden Codefragment wird gezeigt, wie ein Adapter einen neuen Batch von der Engine über seinen Transportproxy anfordert und mithilfe eines Cookies eine einzelne Nachricht an die Engine übermittelt. Die Messaging-Engine ruft die BatchComplete-Methode als Batchrückruf auf, wenn die Verarbeitung des gesamten Batches der übermittelten Nachrichten abgeschlossen ist.

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);  
      }  
}  

Das BizTalk Server SDK enthält Beispiele für die folgenden Adapter: File, HTTP, MSMQ und the Transactional Adapter. All diese Adapter bauen auf einem allgemeinen Baustein auf, dem BaseAdapter. In Version 1.0.1 des BaseAdapter ist der gesamte Code enthalten, den Sie für die Analyse des Vorgangsstatus und zum Erstellen eines neuen Batches zur Übermittlung benötigen.

Racebedingung

Die beiden Aufgaben zur Fehlerbehebung und zum Festlegen des endgültigen Ergebnisses eines übermittelten Batches scheinen einfach. Es sind jedoch Informationen aus verschiedenen Threads erforderlich:

  • Der Adapter verarbeitet Fehler basierend auf Informationen, die von BizTalk Server an die BatchComplete-Rückrufmethode des Adapters übergeben werden. Dieser Rückruf wird auf dem Thread des Adapters ausgeführt.

  • DTCCommitConfirm ist eine Methode für das IBTDTCCommitConfirm-Objekt . Eine instance des IBTDTCCommitConfirm-Objekts wird vom IBTTransportBatch::D one-Batchaufruf zurückgegeben. Dieser instance befindet sich im selben Thread wie der IBTTransportBatch::D one-Aufruf, der sich vom Rückrufthread des Adapters unterscheidet.

    Für jeden Aufruf, den der Adapter an IBTTransportBatch::D ein führt die Messaging-Engine einen entsprechenden Aufruf der Rückrufmethode BatchComplete in einem separaten Thread durch, um das Ergebnis der Batchübermittlung zu melden. In BatchComplete muss der Adapter einen Commit oder ein Rollback für die Transaktion ausführen, je nachdem, ob der Batch erfolgreich war oder fehlgeschlagen ist. In beiden Fällen sollte der Adapter dann DTCCommitConfirm aufrufen, um die status der Transaktion zu melden.

    Eine mögliche Racebedingung besteht, da die BatchComplete-Implementierung des Adapters davon ausgehen kann, dass das von IBTTransportBatch::D one zurückgegebene IBTDTCCommitConfirm-Objekt immer verfügbar ist, wenn BatchComplete ausgeführt wird. BatchComplete kann jedoch in einem separaten Messaging-Engine-Thread aufgerufen werden, noch bevor IBTTransportBatch::D one zurückgegeben wird. Wenn der Adapter versucht, im Rahmen der BatchComplete-Implementierung auf das IBTDTCCommitConfirm-Objekt zuzugreifen, liegt möglicherweise eine Zugriffsverletzung vor, da dieser aufrufende Thread nicht mehr vorhanden ist. Verwenden Sie die folgende Lösung, um dieses Problem zu umgehen.

    Im folgenden Beispiel wird das Problem durch die Verwendung eines Ereignisses gelöst. Hierbei erfolgt der Zugriff auf den Schnittstellenzeiger über eine Eigenschaft, die das Ereignis verwendet. Der Befehl "get" wartet vor dem Fortfahren stets, bis "set" abgeschlossen ist.

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);  

Batchstatuscodes

Der allgemeine Statuscode des Batches gibt das Batchergebnis an. Der Vorgangsstatus gibt den Statuscode der Übermittlung für einzelne Nachrichtenelemente an. Batchfehler können aus unterschiedlichen Gründen auftreten. Beispielsweise könnte ein sicherheitsbezogener Fehler auftreten oder die Nachricht wurde übermittelt, während die Engine heruntergefahren wurde. (Wenn die Engine heruntergefahren wird, akzeptiert es normalerweise keine neuen Aufträge, bereits in Verarbeitung befindliche Aufträge werden jedoch abgeschlossen.) In der folgenden Tabelle werden einige häufig auftretende HRESULT-Werte aufgelistet, die entweder im Batchstatus oder Vorgangsstatus zurückgegeben werden. Außerdem wird angegeben, ob es sich um einen Erfolgs- oder Fehlercode handelt. Die ordnungsgemäße Behandlung dieser Codes wird ausführlicher unter Behandeln von Adapterfehlern beschrieben.

Code (in der Klasse "BTTransportProxy" definiert) Erfolgs-/Fehlercode BESCHREIBUNG
BTS_S_EPM_SECURITY_CHECK_FAILED Erfolg Der Port wurde dafür konfiguriert, eine Sicherheitsüberprüfung durchzuführen und Nachrichten zu verwerfen, die nicht authentifiziert werden konnten. Adapter sollten Batches, die diesen Statuscode zurückgeben, nicht anhalten.
BTS_S_EPM_MESSAGE_SUSPENDED Erfolg Gibt an, dass eine oder mehrere Nachrichten angehalten wurden und dass die Engine die Daten besitzt. Hierbei handelt es sich um einen Erfolgscode, da die Messaging-Engine die Nachrichtenübermittlung akzeptiert hat.
E_BTS_URL_DISALLOWED Fehler Eine Nachricht wurde mit einer ungültigen InboundTransportLocation-Nachricht gesendet.

Batchvorgänge

In der folgenden Tabelle sind die Membermethoden und Vorgänge des IBTTransportBatch-Objekts aufgeführt, die der Adapter verwendet, um einem bestimmten Batch Arbeit hinzuzufügen.

Methodenname Vorgangsart BESCHREIBUNG
SubmitMessage Übermitteln Übermittelt eine Nachricht an die Engine.
SubmitResponseMessage Übermitteln Übermittelt eine Antwortnachricht an die Engine. Dies ist die Antwortnachricht in einem Paar vom Typ "Antwort anfragen".
DeleteMessage Löschen Löscht eine Nachricht, die ein Adapter mit einem nicht blockierenden Sendevorgang erfolgreich über die Verbindung übertragen hat. Adapter, die blockierende Senden verwenden, müssen diese Methode nicht aufrufen, da die Messaging-Engine sie im Namen des Adapters löscht, wenn der Adapter von TransmitMesssage zurückgibttrue.
MoveToSuspendQ MoveToSuspendQ Verschiebt eine Nachricht in die Warteschlange "Angehalten".
Resubmit Erneut übertragen Fordert an, dass eine Nachricht zu einem späteren Zeitpunkt erneut übertragen werden sollte. Dieser Aufruf findet üblicherweise nach einem Übertragungsfehler statt.
MoveToNextTransport MoveToNextTransport Fordert an, dass eine Nachricht mithilfe ihres sekundären Transports übertragen werden soll. Normalerweise erfolgt dieser Aufruf, nachdem alle Wiederholungsversuche ausgeschöpft wurden. Wenn kein sekundärer Transport vorhanden ist, schlägt diese Methode fehl.
SubmitRequestMessage SubmitRequest Übermittelt eine Anforderungsnachricht. Dies ist die Anforderungsnachricht in einem Paar vom Typ "Anforderungsantwort".
CancelRequestForResponse CancelRequestForResponse Benachrichtigt die Engine darüber, dass der Adapter nicht länger auf die Antwortnachricht in einem Paar vom Typ "Anforderungsantwort" warten möchte.
Clear Nicht verfügbar Löscht die gesamte Arbeit aus dem Batch.
Fertig Nicht verfügbar Übermittelt einen Batch mit Nachrichten zur Verarbeitung an die Engine.

Batch Management

Batches werden in der Messaging-Engine im systemeigenen Code implementiert. Aus diesem Grund sollte ein Adapter, der in verwaltetem Code geschrieben wurde, den Runtime Callable Wrapper (RCW) für den Batch auslösen, nachdem er die Batchverarbeitung abgeschlossen hat. Dies geschieht im verwalteten Code mithilfe der Marshal.ReleaseComObject-API . Wichtig: Vergessen Sie nicht, diese API in einer Schleife vom Typ "Während" aufzurufen, bis der ausgegebene Verweiszähler Null erreicht.

BizTalk Server verarbeitet Nachrichten synchron innerhalb eines Batches. Viele Batches können gleichzeitig verarbeitet werden, was eine Möglichkeit bieten kann, die Adapterleistung zu optimieren, indem die Batchgröße in der Anwendungsdomäne angepasst wird. Sie können beispielsweise alle Dateien auf einer FTP-Site verarbeiten lassen (bis zu einer gewissen Grenze). Im Fall von SAP können Sie einen einzelnen Stream in eine Reihe an Nachrichten verarbeiten lassen, die dann als Batch übermittelt werden.

Der Batch, der von einem Adapter verwendet wird, um Vorgänge an BizTalk Server zurückzugeben, muss nicht genau der Liste der Nachrichten entsprechen, die BizTalk Server dem Adapter gibt. Mit anderen Worten: Beim Ausführen von Transaktions sendeten Sie die Vorgänge MoveToNextTransport und MoveToSuspendQ in separate Batches aufteilen. Viele Adapter sortieren einen Batch mit Nachrichten, die für mehrere Endpunkte übermittelt wurden, in separate Listen mit Nachrichten für die Weiterverarbeitung.

Der Punkt ist, dass es keine Regeln (außer denen, die der Transaktion zugeordnet sind) dem Nachrichtenbatching in BizTalk Server zugeordnet sind. Batchverarbeitung ist einfach eine implementierungsspezifische Möglichkeit für den Adapter, Nachrichten in und aus BizTalk Server aufzuteilen.

Ein Adapter kann Nachrichten aus mehreren kleineren Batches, die BizTalk Server in einen größeren Batch für die Antwort auf BizTalk Server übergeben hat, batchieren. Dies kann zu einer beträchtlichen Optimierung in transaktionalen Adaptern führen, die große Mengen an sehr kleinen Nachrichten verarbeiten müssen. Die Gesamtanzahl an Transaktionen pro Nachricht wird auf diese Weise minimiert.

In der Regel erzeugt BizTalk Server sendeseitige Batches zwischen 5 und 10 Nachrichten. Wenn es sich um sehr kleine Nachrichten handelt, kann ein Adapter bis zu 100 Nachrichten oder mehr batchen, bevor er einen Transaktionsbatch mit Löschvorgängen zurück an BizTalk Server sendet. Eine Optimierung wie diese ist nicht einfach zu implementieren. Sie müssen sicherstellen, dass die Nachrichten nicht im Arbeitsspeicher des Adapters hängen bleiben und dort ewig auf einen erreichenden Schwellenwert warten.

Die Bedeutung des Batchings lässt sich an den Leistungszahlen für BizTalk Server für Adapter mit hohem Durchsatz wie MQSeries erkennen. In diesen Adaptern werden Nachrichten mindestens zwei Mal so häufig empfangen, wie gesendet. Standardmäßig verwendet der Empfangsadapter Batches mit 100 Nachrichten, und der Sendeadapter verwendet den Standard BizTalk Server Batch, der angegeben wird.

Transaktionsbatches

Wenn Sie einen Adapter schreiben, der ein Transaktionsobjekt erstellt und an BizTalk Server übergibt, übernehmen Sie die Verantwortung für das Schreiben von Code, der folgendes ausführt:

  • Entscheidet über das endgültige Ergebnis des Batchvorgangs: Commit oder Beenden der Transaktion. Dies hängt möglicherweise von anderen Transaktionszweigen innerhalb des Bereichs dieser transaktion ab, die nicht BizTalk Server abhängig sind, z. B. das Schreiben in eine MsMQ-Warteschlange (Message Queuing) oder einen Transaktionsdatenbankvorgang.

  • Informiert BizTalk Server über das endgültige Ergebnis, indem die IBTDTCCommitConfirm.DTCCommitConfirm-Methode aufgerufen wird. true Das Zurückgeben gibt einen erfolgreichen Commit der Transaktion an. Die Rückgabe false bedeutet einen Fehler und ein Rollback der Transaktion.

    Der Adapter muss BizTalk Server über das Endergebnis der Transaktion informieren, um seine internen Nachverfolgungsdaten zu verwalten. Der Adapter informiert BizTalk Server über das Ergebnis, indem er DTCCommitConfirm aufruft. Wenn der Adapter diese Aktionen nicht durchführt, tritt ein beträchtlicher Speicherverlust auf. Für die MSDTC-Transaktion könnte dann ein Timeout eintreten (und sie schlägt fehl), obwohl alle Vorgänge erfolgreich durchgeführt wurden.