Sdílet prostřednictvím


Uvedení prostředků jako účastníků v transakci

Každý zdroj účasti na transakci spravuje správce prostředků, jejichž akce jsou koordinovaný správcem transakcí. Koordinace se provádí prostřednictvím oznámením na účastníky, kteří mají uveden v transakci prostřednictvím Správce transakcí.

Toto téma popisuje, jak prostředek (nebo více zdrojů) může být uveden v transakci, jakož i různé typy zařazení. Potvrzení transakce v jednofázovém a vícefázovém tématu popisuje, jak lze koordinovat závazek transakce mezi zařazenými prostředky.

Uvedení prostředků v transakci

Chcete-li, aby zdroj k účasti v transakci musí zařadit do transakce. Třída Transaction definuje sadu metod, jejichž názvy začínají enlist, které poskytují tuto funkci. Různé metody zařazení odpovídají různým typům zařazení, které může mít správce prostředků. Konkrétně používají EnlistVolatile metody pro těkavých materiály a EnlistDurable metody pro trvalý zdroje. Životnost (nebo naopak nestálosti) materiálu manager odkazuje na tom, zda správce prostředků podporuje obnovení po selhání. Pokud správce prostředků podporuje obnovení po selhání, přenese data do trvalého úložiště během fáze 1 (připravit) tak, pokud správce prostředků nebude fungovat, můžete zařadit do transakce při obnovení, znovu a správné činnostem podle oznámení obdržená z správce TM. Obecně platí správci těkavých prostředků spravovat těkavých prostředků, jako jsou například struktury dat v paměti (například v paměti zpracováván jako transakce hashtable) a správci trvalý prostředků spravovat prostředky, které mají více trvalé záložní úložiště (například databáze jehož záložní úložiště je disku).

Pro jednoduchost, jakmile se rozhodnete, zda se má použít EnlistDurable nebo EnlistVolatile metoda založená na podporu své prostředků životnost, by měl zařazení materiálu k účasti na dvě fáze potvrzení (2PC) implementací IEnlistmentNotification rozhraní pro váš správce prostředků. Další informace o 2PC naleznete v tématu Potvrzení transakce v jednofázové a vícefázové.

Jeden účastník může zařazení pro více než jedním z těchto protokolů voláním EnlistDurable a EnlistVolatile více než jednou.

Trvalý zařazení

EnlistDurable Metody se používají k zařazení správce prostředků pro účast v transakci jako trvalý prostředek. Očekává se, že je-li správce prostředků trvalý uprostřed transakcí, lze provádět obnovení poté, co načtením zpět do režimu online podle reenlisting (pomocí Reenlist metoda) ve všech transakcích, v nichž byl účastník a nebyla dokončena, fáze 2 a volat RecoveryComplete po dokončení zpracování obnovení. Další informace o obnovení najdete v tématu Provádění obnovení.

EnlistDurable Provést všechny metody Guid objektu jako svůj první parametr. Guid Slouží správcem transakcí, které pokud chcete přidružit trvalý zařazení správce prostředků konkrétní. Jako takové, je nezbytné, že správce prostředků konzistentně používá stejný Guid k identifikaci i přes správci různých prostředků při restartování, v opačném případě obnovení může selhat.

Druhý parametr EnlistDurable metoda je odkaz na objekt, který implementuje správce prostředků k odběru oznámení transakce. Přetížení, které využíváte informuje správce transakcí, zda váš správce prostředků podporuje optimalizaci jedné fáze potvrzení (SPC). Ve většině případů, měli byste implementovat IEnlistmentNotification rozhraní k účasti na dvoufázový potvrzení (2PC). Nicméně pokud chcete k optimalizaci procesu potvrzení, můžete zvážit implementaci ISinglePhaseNotification rozhraní pro certifikát SPC. Další informace o SPC naleznete v tématu Potvrzení transakce v jednofázové a vícefázové a optimalizace pomocí jednofázového potvrzení a propagační jednofázové oznámení.

Třetí parametr je EnlistmentOptions výčtu, jehož hodnota může být buď None nebo EnlistDuringPrepareRequired. Pokud hodnota je nastavena EnlistDuringPrepareRequired, zařazení může zahrnovat správci dalších prostředků při přijetí oznámení připravit z správce transakcí. Nicméně je třeba upozornit na to, že tento typ zařazení není nárok optimalizace jedné fáze potvrzení.

Nestálá zařazení

Správa těkavých prostředků, jako je například mezipaměť by měl zařazení pomocí účastníci EnlistVolatile metody. Tyto objekty nemusí být možné získat výsledku transakce nebo obnovit stav všech transakcí, které se účastní v po selhání systému.

Jak je uvedeno dříve, správce prostředků by Nestálá zařazení, pokud spravuje v paměti, těkavých zdroj. Jednou z výhod pomocí EnlistVolatile je nevede nepotřebné eskalace transakce. Další informace o eskalaci transakcí naleznete v tématu Eskalace správy transakcí. Zařazení nestálosti implikuje rozdíl v tom, jak je zařazení zpracováno správcem transakcí, stejně jako to, co je očekáváno správcem prostředků správce transakcí. Toto je vzhledem k tomu, že správce prostředků těkavých neprovádí obnovení. EnlistVolatile Metody nepřebírají Guid parametr, vzhledem k tomu, že správce prostředků těkavých neprovádí obnovení a by volat Reenlist metodu, kterou je Guid.

Stejně jako u trvalý zařazení označuje podle toho, která přetížení metody, které použijete k zařazení do správce transakcí zda váš správce prostředků podporuje optimalizaci jedné fáze potvrzení. Vzhledem k tomu, že správce prostředků těkavých nelze provést obnovení, žádné informace o obnovení pro těkavých zařazení během fáze Prepare není zapsán. Proto volání RecoveryInformation metodu vede InvalidOperationException.

Následující příklad ukazuje, jak takový objekt jako účastník v transakci pomocí zařazení do seznamu 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

Optimalizace výkonu

Transaction Třída rovněž poskytuje EnlistPromotableSinglePhase metodu k zařazení možné zařazení pro jedné fáze (PSPE). To umožňuje trvalý prostředku manager (SV) pro hostování a "vlastní" transakce, který lze později eskalován jej lze spravovat pomocí příkaz MSDTC v případě potřeby. Další informace o tomto tématu naleznete v tématu Optimalizace pomocí jednofázového potvrzení a promotable jednofázové oznámení.

Viz také