Freigeben über


Verarbeiten von Transaktionen

Transaktive Empfänger

Der Standard Unterschied zwischen Transaktionsempfängern und nicht übersetzten Empfängern besteht darin, dass transaktionsbasierte Empfänger eine explizite MSDTC-Transaktion erstellen und verwenden, um die Atomarität zwischen ihrer Datenquelle und der BizTalk Server MessageBox-Datenbank sicherzustellen. Im Allgemeinen sind alle anderen Aspekte der Adapter identisch.

Beachten Sie, dass bei Anforderungsantwort-Empfangsadaptern nur eine Transaktion zum Senden der ursprünglichen Anforderungsnachricht an die Messaging-Engine verwendet wird. Zum Übermitteln der von der Messaging-Engine an den Adapter gesendeten Nachricht ist eine andere Transaktion erforderlich. Der Grund hierfür ist, dass der Bereich der ersten Transaktion zwischen dem Adapter und der MessageBox-Datenbank liegt. Die nachfolgende Anforderungsnachricht wird erst von der Messaging-Engine an den Adapter gesendet, nachdem ein Commit für die Transaktion der ursprünglichen Anforderungsnachricht ausgeführt wurde.

Im folgenden Diagramm zur Objektinteraktion wird die Interaktion zwischen Adapter und Messaging-Engine während einer transaktionalen Übermittlung eingehender Nachrichten veranschaulicht. In diesem Beispiel werden folgende Interaktionen ausgeführt:

  1. Der Adapter erhält von der Engine einen neuen Batch.

  2. Der Adapter erstellt eine neue MSDTC-Transaktion.

  3. Der Adapter führt einen destruktiven Lesevorgang auf der Datenquelle aus, die in der Transaktion eingetragen wurde.

  4. Der Adapter übermittelt die Nachricht.

  5. Der Adapter ruft Done für den Batch auf und übergibt die MSDTC-Transaktion und den BatchComplete-Rückrufzeiger . Die Engine gibt eine IBTDTCCommitConfirm-Schnittstelle zurück.

  6. Die Engine verarbeitet den Batch, ruft den Adapter auf seine BatchComplete-Implementierung zurück und übermittelt dem Adapter die status der Nachrichtenverarbeitung.

  7. Wenn der Batch erfolgreich war, committet der Adapter die Transaktion und ruft die IBTDTCCommitConfirm.DTCCommitConfirm-API mit einem true Wert auf, der einen Commit angibt.

    Abbildung, die die Interaktion zwischen dem Adapter und der Messaging-Engine während einer Transaktionsübermittlung eingehender Nachrichten zeigt.

Transaktive Sender

Transaktive Adapter sind nicht transaktiven Adaptern im Allgemeinen sehr ähnlich. Der Hauptunterschied besteht darin, dass die Daten in einer Nachricht von transaktiven Adaptern an eine Ressource gesendet werden, die vom Adapter in einer MSDTC-Transaktion eingetragen wurde.

Implementierungstipp: Für transaktionente Sendevorgänge sollte der Adapter dieselbe MSDTC-Transaktion verwenden, um die Daten in das Ziel zu schreiben und über den IBTTransportBatch.DeleteMessage-Methodenaufruf zu löschen. Eine Transaktion muss nur für diese beiden Vorgänge ausgeführt werden. Alle anderen Vorgänge wie IBTTransportBatch.Resubmit, IBTTransportBatch.MoveToNextTransport und IBTTransportBatch.MoveToSuspendQ müssen nicht durchgeführt werden. Der Grund hierfür ist, dass eine Transaktion implizit von der Engine verwendet wird und diese Transaktionstypen hinsichtlich des Ziels nicht atomarisch sein müssen.

Im folgenden Diagramm zur Objektinteraktion werden die Interaktionen zwischen Adapter und Engine veranschaulicht. Die Ereignisse finden in der folgenden Reihenfolge statt:

  1. Die Engine erhält einen neuen Batch vom Adapter.

  2. Die Engine fügt dem neuen Batch zwei Nachrichten hinzu.

  3. Die Engine ruft Done für den Batch auf, sodass der Adapter den Batch in seine interne Übertragungswarteschlange sendet, die vom Threadpool verwaltet wird.

  4. Der Adapter erstellt eine neue MSDTC-Transaktion.

  5. Der Adapter sendet die Nachrichten, in denen das Ziel der MSDTC-Transaktion eingetragen ist. Dies kann beispielsweise das Schreiben in eine SQL Server-Datenbank sein.

  6. Nach der Übertragung ruft der Adapter einen neuen Batch von der Engine ab.

  7. Der Adapter ruft DeleteMessage für die Nachrichten auf, die er erfolgreich übertragen hat.

  8. Der Adapter ruft Done auf, wenn der Batch seine DTC-Transaktion übergibt. Die Engine gibt eine IBTDTCCommitConfirm-Schnittstelle zurück.

  9. Die Engine verarbeitet den Batch und löscht die Nachrichten aus der Anwendungswarteschlange.

  10. Die Engine ruft die IBTBatchCallback-Schnittstelle des Adapters mit Informationen über den Erfolg der Löschvorgänge zurück.

  11. Wenn der Batch erfolgreich verarbeitet wurde, führt der Adapter einen Commit für die Transaktion aus.

  12. Der Adapter ruft IBTDTCCommitConfirm.DTCCommitConfirm auf , um die Engine darüber zu informieren, dass die Transaktion erfolgreich committet wurde.

    Abbildung, die die Interaktionen zwischen dem Adapter und der Engine zeigt.

Transaktive 'Antwort anfragen'-Adapter

Im Gegensatz zu bidirektionalen Empfangsvorgängen können bidirektionale Sendevorgänge mit der gleichen DTC-Transaktion ausgeführt werden. Transacted solicit-response-Adapter sollten denselben IBTTransportBatch für die Vorgänge SubmitResponseMessage und DeleteMessage verwenden. Für diesen Batch sollte die gleiche MSDTC-Transaktion wie zum Senden und Empfangen von Nachrichtenpaaren vom Typ Antwort anfragen verwendet werden. Dies stellt die Unteilbarkeit des Antwort anfragen-Nachrichtenaustauschs sicher.

Dienstkomponenten und BYOT

Die Messaging-Engine-APIs erfordern die Bereitstellung einer MSDTC-Transaktion. Einige .NET-Komponenten wurden jedoch zur Verwendung als Serviced Components entworfen und bieten keine Möglichkeit zum programmgesteuerten Löschen oder Zusichern von Transaktionen. Stattdessen werden Transaktionen automatisch von der COM+-Laufzeit dieser Plattform zugesichert.

In diesen Szenarien sollte vom Adapter BYOT (Bring Your Own Transaction) verwendet werden. Hierdurch kann der Adapter eine MSDTC-Transaktion erstellen, die von der Transaktion verwendete .NET-Komponente instanziieren und das Vererben der erstellten Transaktion an diese Komponente ermöglichen, sodass keine eigene Transaktion von der Transaktion erstellt werden muss. Die .NET Framework stellt zu diesem Zweck System.EnterpriseServices.BYOT bereit. Das SDK BaseAdapter stellt für diesen Zweck die Hilfsklasse BYOTTransaction bereit.

Vermeiden von Racebedingungen

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 die folgenden Aktionen ausführt:

  • Behebt Fehler in Nachrichten, die dem Batch zugeordnet sind.

  • Legt das Endergebnis der Transaktion fest, die dem Batchvorgang zugeordnet ist.

    Der Adapter muss BizTalk Server über das Endergebnis der Transaktion informieren, um seine internen Nachverfolgungsdaten beizubehalten. Der Adapter informiert BizTalk Server über das Ergebnis, indem er DTCConfirmCommit aufruft. Wenn dies nicht vom Adapter ausgeführt wird, tritt ein wesentlicher Speicherverlust auf.

    Die beiden oben aufgeführten Aufgaben zum Beheben von Fehlern und zum Festlegen des Endergebnisses scheinen einfach, sind jedoch tatsächlich von Informationen aus verschiedenen Threads abhängig:

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

  • DTCConfirmCommit 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 Thread des Adapters unterscheidet.

  • Für jeden Aufruf des Adapters an IBTTransportBatch::D one gibt es einen entsprechenden Rückruf, BatchComplete, der von der Messaging-Engine in einem separaten Thread aufgerufen wird, 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 DTCConfirmCommit aufrufen, um die status der Transaktion an die Messaging-Engine 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.

    Im folgenden Beispiel wird das Problem mithilfe eines Ereignisses gelöst. Hierbei erfolgt der Zugriff auf den Schnittstellenzeiger über eine Eigenschaft, die das Ereignis verwendet. Die get-Funktion wartet immer auf die set-Funktion.

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

Weisen Sie dieser Eigenschaft nun den Rückgabewert von IBTTransportBatch::D one zu, und verwenden Sie ihn im BatchComplete-Aufruf .

Weitere Informationen

Transaktionsnachrichtenbatches