Uwaga
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Każdy zasób uczestniczący w transakcji jest zarządzany przez menedżera zasobów, którego akcje są koordynowane przez menedżera transakcji. Koordynacja odbywa się za pośrednictwem powiadomień przekazanych subskrybentom, którzy zarejestrowali się w transakcji za pośrednictwem menedżera transakcji.
W tym temacie opisano, jak zasób (lub wiele zasobów) można zarejestrować w transakcji, a także różne typy rejestracji. W temacie Zatwierdzanie transakcji w Single-Phase i wielofazowe opisano sposób koordynowania zatwierdzania transakcji między zasobami wymienionymi na liście.
Rejestrowanie zasobów w transakcji
Aby zasób brał udział w transakcji, musi zarejestrować się w transakcji. Klasa Transaction definiuje zestaw metod, których nazwy zaczynają się od Enlist , które zapewniają tę funkcję. Różne metody rejestracji odpowiadają różnym typom rejestracji, które może mieć menedżer zasobów. W szczególności używasz EnlistVolatile metod dla nietrwałych zasobów i EnlistDurable metody dla zasobów trwałych. Trwałość (lub odwrotnie zmienność) menedżera zasobów odnosi się do tego, czy menedżer zasobów obsługuje odzyskiwanie po awarii. Jeśli menedżer zasobów obsługuje odzyskiwanie po awarii, utrwala dane w magazynie trwałym podczas fazy 1 (przygotowanie), tak aby jeśli menedżer zasobów ulegnie awarii, może ponownie zarejestrować się w transakcji po odzyskiwaniu i wykonać odpowiednie akcje na podstawie powiadomień otrzymanych z TM. Ogólnie rzecz biorąc, menedżerowie zasobów nietrwałych zarządzają zasobami, które są ulotne, takimi jak struktura danych w pamięci (na przykład przetwarzana tabela haszująca w pamięci), natomiast menedżerowie zasobów trwałych zarządzają zasobami z bardziej trwałym zapleczem, takim jak baza danych z zapleczem na dysku.
Dla ułatwienia, po podjęciu decyzji, czy użyć metody EnlistDurable czy EnlistVolatile na podstawie wsparcia trwałości zasobu, należy zarejestrować zasób do uczestnictwa w dwufazowym zatwierdzaniu (2PC) poprzez implementację interfejsu IEnlistmentNotification dla menedżera zasobów. Aby uzyskać więcej informacji na temat 2PC, zobacz Zatwierdzanie transakcji w Single-Phase i fazach wieloetapowych.
Jeden uczestnik może zarejestrować się do więcej niż jednego z tych protokołów przez wywołanie EnlistDurable i EnlistVolatile wiele razy.
Trwałe zobowiązanie
Metody EnlistDurable służą do rejestracji menedżera zasobów w celu udziału w transakcji jako trwałego zasobu. Oczekuje się, że jeśli trwały menedżer zasobów zostanie wyłączony w trakcie transakcji, może wykonać odzyskiwanie po ponownym uruchomieniu przez ponowne zarejestrowanie się za pomocą metody Reenlist we wszystkich transakcjach, w których był uczestnikiem i nie zakończył fazy 2, oraz wywołać RecoveryComplete po zakończeniu przetwarzania odzyskiwania. Aby uzyskać więcej informacji na temat odzyskiwania, zobacz Wykonywanie odzyskiwania.
Wszystkie EnlistDurable metody przyjmują Guid obiekt jako pierwszy parametr. Element Guid jest używany przez menedżera transakcji do skojarzenia trwałego uczestnictwa z danym menedżerem zasobów. W związku z tym konieczne jest, aby menedżer zasobów konsekwentnie używał tego samego Guid do identyfikowania się nawet w różnych menedżerach zasobów po ponownym uruchomieniu, w przeciwnym razie odzyskiwanie może zakończyć się niepowodzeniem.
Drugi parametr EnlistDurable metody jest odwołaniem do obiektu, który menedżer zasobów implementuje w celu odbierania powiadomień transakcji. Przeciążenie używane informuje menedżera transakcji, czy menedżer zasobów obsługuje optymalizację zatwierdzania jednofazowego (SPC). W większości przypadków powinno się zaimplementować interfejs IEnlistmentNotification do udziału w Two-Phase Commit (2PC). Jeśli jednak chcesz zoptymalizować proces zatwierdzania, możesz rozważyć zaimplementowanie interfejsu ISinglePhaseNotification dla usługi SPC. Aby uzyskać więcej informacji na temat SPC, zobacz Zatwierdzanie transakcji w Single-Phase i wielofazowe oraz optymalizacja przy użyciu jednofazowego zatwierdzania i promowalnego jednofazowego powiadomienia oraz Optymalizacja przy użyciu jednofazowego zatwierdzania transakcji i promowalnego jednofazowego powiadomienia.
Trzeci parametr to EnlistmentOptions wyliczenie, którego wartość może być None lub EnlistDuringPrepareRequired. Jeśli wartość jest ustawiona na EnlistDuringPrepareRequired, rejestracja może zarejestrować dodatkowych menedżerów zasobów po otrzymaniu powiadomienia Prepare od menedżera transakcji. Należy jednak pamiętać, że ten typ rejestracji nie kwalifikuje się do optymalizacji zatwierdzania jednofazowego.
Nietrwała rejestracja
Uczestnicy zarządzający nietrwałymi zasobami, takimi jak pamięć podręczna, powinni zarejestrować się przy użyciu EnlistVolatile metod . Takie obiekty mogą nie być w stanie uzyskać wyniku transakcji lub odzyskać stan każdej transakcji, w której uczestniczą po awarii systemu.
Jak wspomniano wcześniej, menedżer zasobów utworzy niestabilną rejestrację, jeśli zarządza zasobem w pamięci, nietrwałym. Jedną z zalet używania EnlistVolatile jest to, że nie wymusza niepotrzebnej eskalacji transakcji. Aby uzyskać więcej informacji na temat eskalacji transakcji, zobacz Temat Eskalacja zarządzania transakcjami . Włączenie zmienności transakcyjnej oznacza zarówno różnicę w sposobie, w jaki rejestracja jest obsługiwana przez menedżera transakcji, jak i w tym, czego oczekuje menedżer transakcji od menedżera zasobów. Dzieje się tak, ponieważ nietrwały menedżer zasobów nie wykonuje odzyskiwania. Metody EnlistVolatile nie przyjmują parametru Guid, ponieważ menedżer zasobów o charakterze nietrwałym nie prowadzi odzyskiwania i nie wywołuje metody Reenlist, która wymaga Guid.
Podobnie jak w przypadku trwałych zapisów, każda metoda przeciążenia używana do rejestracji informuje menedżera transakcji, czy menedżer zasobów obsługuje optymalizację zatwierdzania jednofazowego. Ponieważ nietrwały menedżer zasobów nie może wykonać odzyskiwania, żadne informacje odzyskiwania nie są zapisywane dla nietrwałej rejestracji w fazie przygotowywania. Dlatego wywołanie metody RecoveryInformation skutkuje InvalidOperationException.
W poniższym przykładzie pokazano, jak zarejestrować taki obiekt jako uczestnik transakcji przy użyciu EnlistVolatile metody .
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
Optymalizowanie wydajności
Klasa Transaction udostępnia również metodę EnlistPromotableSinglePhase rejestrowania Rejestracji Jednofazowej z Możliwością Awansowania (PSPE, Promotable Single Phase Enlistment). Umożliwia to trwałemu menedżerowi zasobów (RM) hostowanie i "posiadanie" transakcji, którą później można eskalować do zarządzania przez MSDTC w razie potrzeby. Aby uzyskać więcej informacji na ten temat, zobacz Optymalizacja przy użyciu zatwierdzania jednofazowego i promowalnego powiadomienia jednofazowego.