Resources inschakelen als deelnemers aan een transactie
Elke resource die deelneemt aan een transactie wordt beheerd door een resourcemanager, waarvan de acties worden gecoördineerd door een transactiebeheerder. De coördinatie wordt uitgevoerd via meldingen die worden gegeven aan abonnees die een transactie hebben ingeschreven via de transactiemanager.
In dit onderwerp wordt beschreven hoe een resource (of meerdere resources) kan worden opgenomen in een transactie, evenals de verschillende typen opname. In het onderwerp Over het doorvoeren van een transactie in één fase en in meerdere fasen wordt beschreven hoe transactieverzegging kan worden gecoördineerd tussen opgenomen resources.
Resources in een transactie inschakelen
Als u wilt dat een resource deelneemt aan een transactie, moet deze in de transactie worden opgenomen. De Transaction klasse definieert een set methoden waarvan de namen beginnen met Enlist die deze functionaliteit bieden. De verschillende enlist-methoden komen overeen met de verschillende typen aanhaling die een resourcemanager mogelijk heeft. U gebruikt met name de EnlistVolatile methoden voor vluchtige resources en de EnlistDurable methode voor duurzame resources. De duurzaamheid (of omgekeerd de volatiliteit) van een resourcemanager verwijst naar of de resourcemanager foutenherstel ondersteunt. Als een resourcemanager ondersteuning biedt voor herstel na fouten, worden er gegevens bewaard in duurzame opslag tijdens fase1 (voorbereiding), zodat als de resourcemanager uitvalt, de transactie opnieuw kan worden opgenomen bij herstel en de juiste acties kan worden uitgevoerd op basis van de meldingen die zijn ontvangen van de TM. Over het algemeen beheren vluchtige resourcebeheerders vluchtige resources, zoals een gegevensstructuur in het geheugen (bijvoorbeeld een transacted-hashtable in het geheugen), en duurzame resourcemanagers beheren resources die een persistenter back-uparchief hebben (bijvoorbeeld een database waarvan de back-upopslag een schijf is).
Voor het gemak moet u, nadat u hebt besloten of u de EnlistDurable of EnlistVolatile methode wilt gebruiken op basis van de ondersteuning voor duurzaamheid van uw resource, uw resource inschakelen om deel te nemen aan twee fasen (2PC) door de IEnlistmentNotification interface voor uw resourcemanager te implementeren. Zie Een transactie doorvoeren in één fase en meerdere fasen voor meer informatie over 2PC.
Eén deelnemer kan meer dan één van deze protocollen inschakelen door te bellen EnlistDurable en EnlistVolatile meerdere keren.
Duurzame aanmelding
De EnlistDurable methoden worden gebruikt om een resourcemanager in te schakelen voor deelname aan de transactie als een duurzame resource. Het wordt verwacht dat als een duurzame resourcemanager midden in een transactie wordt geplaatst, het herstel kan uitvoeren zodra deze weer online is gebracht door de lijst opnieuw in te schakelen (met behulp van de Reenlist methode) in alle transacties waarin het een deelnemer was en fase 2 niet heeft voltooid en de aanroep RecoveryComplete zodra de herstelverwerking is voltooid. Zie Herstel uitvoeren voor meer informatie over herstel.
De EnlistDurable methoden nemen allemaal een Guid object als eerste parameter. De Guid gegevens worden door de transactiebeheerder gebruikt om een duurzame opname aan een bepaalde resourcemanager te koppelen. Daarom is het noodzakelijk dat een resourcemanager consistent hetzelfde Guid gebruikt om zichzelf te identificeren, zelfs bij het opnieuw opstarten, anders kan het herstel mislukken.
De tweede parameter van de EnlistDurable methode is een verwijzing naar het object dat resource manager implementeert voor het ontvangen van transactiemeldingen. De overbelasting die u gebruikt, informeert de transactiebeheerder of uw Resource Manager de optimalisatie van SPC (Single Phase Commit) ondersteunt. Meestal implementeert u de IEnlistmentNotification interface om deel te nemen aan tweefasen doorvoeren (2PC). Als u het doorvoerproces echter wilt optimaliseren, kunt u overwegen om de ISinglePhaseNotification interface voor SPC te implementeren. Zie Voor meer informatie over SPC het doorvoeren van een transactie in één fase en multifase en optimalisatie met behulp van single phase commit en Promotable Single Phase Notification.
De derde parameter is een EnlistmentOptions opsomming, waarvan de waarde kan zijn None of EnlistDuringPrepareRequired. Als de waarde is ingesteld op EnlistDuringPrepareRequired, kan de aanmeldlijst extra resourcemanagers inschakelen bij het ontvangen van de melding Voorbereiden van de transactiebeheerder. U moet er echter rekening mee houden dat dit type opname niet in aanmerking komt voor de optimalisatie van het doorvoeren van één fase.
Vluchtige opname
Deelnemers die vluchtige resources beheren, zoals een cache, moeten de EnlistVolatile methoden gebruiken. Dergelijke objecten kunnen mogelijk het resultaat van een transactie niet verkrijgen of de status van een transactie herstellen waaraan ze deelnemen na een systeemfout.
Zoals eerder vermeld, zou een resourcemanager een vluchtige aanhaling maken als deze een in-memory, vluchtige resource beheert. Een van de voordelen van het gebruik EnlistVolatile is dat er geen onnodige escalatie van de transactie wordt afgedwongen. Zie het onderwerp Escalatie van transactiebeheer voor meer informatie over transactie-escalatie . Het inschakelen van volatiliteit impliceert zowel een verschil in de manier waarop de opname wordt verwerkt door de transactiemanager, als wat wordt verwacht van de resourcemanager door de transactiemanager. Dit komt doordat een vluchtige Resource Manager geen herstel uitvoert. De EnlistVolatile methoden nemen Guid geen parameter, omdat een vluchtige resourcemanager geen herstel uitvoert en de Reenlist methode die een Guidnodig heeft, niet aanroept.
Net als bij duurzame ingebruiknames, welke overbelastingsmethode u gebruikt om aan te geven aan de transactiebeheerder of uw resourcemanager ondersteuning biedt voor optimalisatie van single phase commit. Omdat een vluchtige Resource Manager geen herstel kan uitvoeren, worden er geen herstelgegevens geschreven voor een vluchtige opname tijdens de voorbereidingsfase. Daarom resulteert het aanroepen van de RecoveryInformation methode in een InvalidOperationException.
In het volgende voorbeeld ziet u hoe u een dergelijk object als deelnemer aan een transactie kunt inschakelen met behulp van de EnlistVolatile methode.
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
Prestaties optimaliseren
De Transaction klasse biedt ook de EnlistPromotableSinglePhase methode om een Promotable Single Phase Enlistment (PSPE) in te schakelen. Hierdoor kan een durable resource manager (RM) een transactie hosten en 'bezitten' die later kan worden geëscaleerd om indien nodig door de MSDTC te worden beheerd. Zie Optimalisatie met behulp van single phase Commit en Promotable Single Phase Notification voor één fase voor meer informatie hierover.