Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Jede Ressource, die an einer Transaktion teilnimmt, wird von einem Ressourcenmanager verwaltet, dessen Aktionen von einem Transaktionsmanager koordiniert werden. Die Koordination erfolgt durch Benachrichtigungen an Abonnenten, die sich zu einer Transaktion über den Transaktionsmanager angemeldet haben.
In diesem Thema wird erläutert, wie eine Ressource (oder mehrere Ressourcen) in einer Transaktion sowie die verschiedenen Arten der Einlistung aufgelistet werden können. Im Thema Ausführen eines Einphasen- oder Mehrphasencommits für eine Transaktion wird beschrieben, wie ein Transaktionscommit unter eingetragenen Ressourcen koordiniert werden kann.
Einbeziehen von Ressourcen in eine Transaktion
Damit eine Ressource an einer Transaktion teilnimmt, muss sie sich in der Transaktion anmelden. Die Transaction Klasse definiert eine Reihe von Methoden, deren Namen mit Enlist beginnen, die diese Funktionalität bereitstellen. Die verschiedenen Enlist-Methoden entsprechen den verschiedenen Typen von Listen, die ein Ressourcenmanager möglicherweise hat. Insbesondere verwenden Sie die EnlistVolatile Methoden für veränderliche Ressourcen und die EnlistDurable Methode für dauerhafte Ressourcen. Die Haltbarkeit (oder umgekehrt die Volatilität) eines Ressourcenmanagers bezieht sich darauf, ob der Ressourcenmanager fehlerwiederherstellung unterstützt. Wenn ein RM die Wiederherstellung nach einem Fehler unterstützt, legt er Daten während Phase 1 (Vorbereitung) in einem permanenten Speicher ab, damit er sich im Falle eines Ausfalls nach der Wiederherstellung erneut in die Transaktion eintragen und entsprechend den Benachrichtigungen des TM geeignete Aktionen ausführen kann. Im Allgemeinen verwalten flüchtige Ressourcenmanager flüchtige Ressourcen wie z. B. eine In-Memory-Datenstruktur (z. B. eine in-Memory-Transacted-Hashtable), und dauerhafte Ressourcenmanager verwalten Ressourcen, die über einen beständigeren persistenten Speicher verfügen (z. B. eine Datenbank, deren Speicher auf einer Festplatte basiert).
Aus Gründen der Einfachheit sollten Sie, nachdem Sie entschieden haben, ob Sie die Methode EnlistDurable oder EnlistVolatile basierend auf der Haltbarkeitsunterstützung Ihrer Ressource verwenden, Ihre Ressource anmelden, um am Two Phase Commit (2PC) teilzunehmen, indem Sie die IEnlistmentNotification Schnittstelle für Ihren Ressourcen-Manager implementieren. Weitere Informationen zu 2PC finden Sie unter Ausführen eines Einphasen- oder Mehrphasencommits für eine Transaktion.
Ein einzelner Teilnehmer kann sich für mehr als eines dieser Protokolle anmelden, indem er EnlistDurable und EnlistVolatile mehrfach verwendet.
Dauerhafte Einberufung
Die EnlistDurable Methoden werden verwendet, um die Teilnahme eines Ressourcenmanagers als dauerhafte Ressource an der Transaktion zu ermöglichen. Wenn ein dauerhafter RM während einer Transaktion durch eine Unterbrechung ausfällt, wird erwartet, dass er eine Wiederherstellung durchführen kann, sobald er wieder online ist, indem er sich erneut (mithilfe der Reenlist-Methode) in alle Transaktionen einträgt, an denen er teilgenommen und für die er die Phase 2 nicht abgeschlossen hat. Nach Beendigung des Wiederherstellungsprozesses muss er zudem RecoveryComplete aufrufen. Weitere Informationen zur Wiederherstellung finden Sie unter Ausführen der Wiederherstellung.
Die EnlistDurable-Methoden nehmen alle ein Guid-Objekt als ersten Parameter. Das Guid wird vom Transaktionsmanager verwendet, um einen dauerhaften Eintrag mit einem bestimmten Ressourcenmanager zu verbinden. Daher ist es zwingend erforderlich, dass ein Ressourcenmanager immer dasselbe Guid verwendet, um sich selbst zu identifizieren, sogar über verschiedene Ressourcenmanager hinweg, ansonsten kann die Wiederherstellung fehlschlagen.
Der zweite Parameter der EnlistDurable Methode ist ein Verweis auf das Objekt, das der Ressourcen-Manager zum Empfangen von Transaktionsbenachrichtigungen implementiert. Die von Ihnen verwendete Überladung informiert den TM darüber, ob Ihr RM die Einphasencommit(SPC)-Optimierung unterstützt. Meistens implementieren Sie die IEnlistmentNotification Schnittstelle, um an Two-Phase Commit (2PC) teilzunehmen. Wenn Sie den Commitprozess jedoch optimieren möchten, können Sie die Implementierung der ISinglePhaseNotification Schnittstelle für SPC in Betracht ziehen. Weitere Informationen zu SPC finden Sie unter Ausführen eines Einphasen- oder Mehrphasencommits für eine Transaktion und Optimierung mit Einphasencommit und heraufstufbarer Einphasenbenachrichtigung.
Der dritte Parameter ist eine EnlistmentOptions-Enumeration, deren Wert None oder EnlistDuringPrepareRequired sein kann. Wenn der Wert auf EnlistDuringPrepareRequired festgelegt ist, kann die Auflistung zusätzliche Ressourcenmanager auflisten, nachdem sie die Benachrichtigung "Vorbereiten" vom Transaktions-Manager erhalten haben. Sie sollten sich jedoch bewusst sein, dass diese Art von Beitritt nicht für die Single Phase Commit-Optimierung geeignet ist.
Unbeständiger Wehrdienst
Teilnehmer, die flüchtige Ressourcen, wie z. B. einen Cache, verwalten, sollten sich mithilfe der EnlistVolatile-Methoden eintragen. Solche Objekte können möglicherweise nicht das Ergebnis einer Transaktion abrufen oder den Status einer Transaktion wiederherstellen, an der sie teilnehmen, nachdem ein Systemfehler aufgetreten ist.
Wie bereits erwähnt, würde ein Ressourcenmanager eine veränderliche Einlistung vornehmen, wenn er eine speicherinterne, veränderliche Ressource verwaltet. Einer der Vorteile der Verwendung EnlistVolatile besteht darin, dass sie keine unnötige Eskalation der Transaktion erzwingt. Weitere Informationen zur Transaktionseskalation finden Sie im Thema "Transaktionsverwaltungseskalation ". Eine flüchtige Eintragung impliziert einerseits einen Unterschied in der Handhabung der Eintragung durch den Transaktions-Manager und andererseits einen Unterschied darin, was der Transaktions-Manager vom Ressourcen-Manager erwartet. Dies liegt daran, dass ein flüchtiger Ressourcenmanager keine Wiederherstellung durchführt. Die EnlistVolatile-Methoden verwenden keinen Guid-Parameter, da ein volatiler Ressourcenmanager keine Wiederherstellung durchführt und die Reenlist-Methode, die eine Guid benötigt, nicht aufrufen würde.
Wie bei den dauerhaften Eintragungen erkennt der TM an der Überladungsmethode, die Sie zur Eintragung verwenden, ob Ihr RM die Einphasencommit-Optimierung unterstützt. Da ein flüchtiger Ressourcen-Manager keine Wiederherstellung durchführen kann, werden während der Vorbereitungsphase für eine flüchtige Eintragung keine Wiederherstellungsinformationen geschrieben. Daher führt das Aufrufen der RecoveryInformation Methode zu einer InvalidOperationException.
Das folgende Beispiel zeigt, wie Sie ein solches Objekt als Teilnehmer einer Transaktion mithilfe der EnlistVolatile Methode auflisten.
static void Main(string[] args)
{
try
{
using (TransactionScope scope = new TransactionScope())
{
//Create an enlistment object
myEnlistmentClass myEnlistment = new myEnlistmentClass();
//Enlist on the current transaction with the enlistment object
Transaction.Current.EnlistVolatile(myEnlistment, EnlistmentOptions.None);
//Perform transactional work here.
//Call complete on the TransactionScope based on console input
ConsoleKeyInfo c;
while(true)
{
Console.Write("Complete the transaction scope? [Y|N] ");
c = Console.ReadKey();
Console.WriteLine();
if ((c.KeyChar == 'Y') || (c.KeyChar == 'y'))
{
scope.Complete();
break;
}
else if ((c.KeyChar == 'N') || (c.KeyChar == 'n'))
{
break;
}
}
}
}
catch (System.Transactions.TransactionException ex)
{
Console.WriteLine(ex);
}
catch
{
Console.WriteLine("Cannot complete transaction");
throw;
}
}
class myEnlistmentClass : IEnlistmentNotification
{
public void Prepare(PreparingEnlistment preparingEnlistment)
{
Console.WriteLine("Prepare notification received");
//Perform transactional work
//If work finished correctly, reply prepared
preparingEnlistment.Prepared();
// otherwise, do a ForceRollback
preparingEnlistment.ForceRollback();
}
public void Commit(Enlistment enlistment)
{
Console.WriteLine("Commit notification received");
//Do any work necessary when commit notification is received
//Declare done on the enlistment
enlistment.Done();
}
public void Rollback(Enlistment enlistment)
{
Console.WriteLine("Rollback notification received");
//Do any work necessary when rollback notification is received
//Declare done on the enlistment
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
Console.WriteLine("In doubt notification received");
//Do any work necessary when in doubt notification is received
//Declare done on the enlistment
enlistment.Done();
}
}
Public Shared Sub Main()
Try
Using scope As TransactionScope = New TransactionScope()
'Create an enlistment object
Dim myEnlistmentClass As New EnlistmentClass
'Enlist on the current transaction with the enlistment object
Transaction.Current.EnlistVolatile(myEnlistmentClass, EnlistmentOptions.None)
'Perform transactional work here.
'Call complete on the TransactionScope based on console input
Dim c As ConsoleKeyInfo
While (True)
Console.Write("Complete the transaction scope? [Y|N] ")
c = Console.ReadKey()
Console.WriteLine()
If (c.KeyChar = "Y") Or (c.KeyChar = "y") Then
scope.Complete()
Exit While
ElseIf ((c.KeyChar = "N") Or (c.KeyChar = "n")) Then
Exit While
End If
End While
End Using
Catch ex As TransactionException
Console.WriteLine(ex)
Catch
Console.WriteLine("Cannot complete transaction")
Throw
End Try
End Sub
End Class
Public Class EnlistmentClass
Implements IEnlistmentNotification
Public Sub Prepare(ByVal myPreparingEnlistment As PreparingEnlistment) Implements System.Transactions.IEnlistmentNotification.Prepare
Console.WriteLine("Prepare notification received")
'Perform transactional work
'If work finished correctly, reply with prepared
myPreparingEnlistment.Prepared()
End Sub
Public Sub Commit(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.Commit
Console.WriteLine("Commit notification received")
'Do any work necessary when commit notification is received
'Declare done on the enlistment
myEnlistment.Done()
End Sub
Public Sub Rollback(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.Rollback
Console.WriteLine("Rollback notification received")
'Do any work necessary when rollback notification is received
'Declare done on the enlistment
myEnlistment.Done()
End Sub
Public Sub InDoubt(ByVal myEnlistment As Enlistment) Implements System.Transactions.IEnlistmentNotification.InDoubt
Console.WriteLine("In doubt notification received")
'Do any work necessary when in doubt notification is received
'Declare done on the enlistment
myEnlistment.Done()
End Sub
End Class
Optimieren der Leistung
Die Transaction-Klasse stellt die EnlistPromotableSinglePhase-Methode auch bereit, um eine Erweiterbare Einphaseneintragung (PSPE) vorzunehmen. Auf diese Weise kann ein beständiger Ressourcenmanager (RM) eine Transaktion hosten und "besitzen", die später, falls erforderlich, zur Verwaltung an den MSDTC übergeben werden kann. Weitere Informationen hierzu finden Sie unter Optimierung durch „Single Phase Commit“ und „Promotable Single Phase Notification“.