Sdílet prostřednictvím


Použití System.Transactions

platí pro:SQL Server

Obor názvů System.Transactions poskytuje transakční architekturu, která je plně integrovaná s integrací ADO.NET a modulu CLR (Common Language Runtime) SQL Serveru. Třída System.Transactions.TransactionScope vytvoří transakční blok kódu implicitně zařazením připojení do distribuované transakce. Na konci bloku kódu označeného TransactionScopeje nutné volat metodu Complete . Metoda Dispose je vyvolána při spuštění programu opustí blok kódu, což způsobí, že transakce bude ukončena pokud není volána metoda Complete. Pokud byla vyvolána výjimka, která způsobí, že kód opustí obor, transakce je považována za ukončenou.

Doporučujeme použít blok using, abyste zajistili, že Dispose metoda je volána na objekt TransactionScope při ukončení bloku using. Selhání potvrzení nebo vrácení čekajících transakcí může vážně snížit výkon, protože výchozí časový limit pro TransactionScope je jedna minuta. Pokud nepoužíváte příkaz using, musíte provést veškerou práci v bloku Try a explicitně volat metodu Dispose v bloku Finally.

Pokud dojde k výjimce v rámci TransactionScope, transakce je označena jako nekonzistentní a je opuštěna. Po odstranění TransactionScope se vrátí zpět. Pokud nedojde k žádné výjimce, zúčastněné transakce potvrzení.

TransactionScope by se měly používat jenom v případě, že se k místním a vzdáleným zdrojům dat nebo externím správcům prostředků přistupuje, protože TransactionScope vždy způsobí zvýšení úrovně transakcí, i když se používají jenom v kontextu připojení.

Třída TransactionScope ve výchozím nastavení vytvoří transakci s System.Transactions.Transaction.IsolationLevelSerializable. V závislosti na vaší aplikaci můžete zvážit snížení úrovně izolace, abyste se vyhnuli vysokým kolizím v aplikaci.

Poznámka

Doporučujeme provádět pouze aktualizace, vkládání a odstraňování v rámci distribuovaných transakcí na vzdálených serverech, protože spotřebovávají významné databázové prostředky. Pokud se operace provede na místním serveru, distribuovaná transakce není nutná a místní transakce bude stačit. SELECT příkazy mohou zbytečně uzamknout databázové prostředky a v některých scénářích může být nutné použít transakce pro výběr. Jakákoli jiná než databázová práce by měla být provedena mimo rozsah transakce, pokud nezahrnuje jiné správce prostředků transakce.

I když výjimka v rozsahu transakce brání transakce v potvrzení, TransactionScope třída nemá žádné zřízení pro vrácení změn provedené kódem mimo rozsah samotné transakce. Pokud potřebujete provést nějakou akci při vrácení transakce zpět, musíte napsat vlastní implementaci System.Transactions.IEnlistmentNotification rozhraní a explicitně přidat do transakce.

Příklady

Pokud chcete pracovat s System.Transactions, musíte mít odkaz na soubor System.Transactions.dll.

Následující kód ukazuje, jak vytvořit transakci, která může být povýšena proti dvěma různým instancím SQL Serveru. Tyto instance jsou reprezentovány dvěma různými System.Data.SqlClient.SqlConnection objekty, které jsou zabaleny do bloku TransactionScope. Kód vytvoří blok TransactionScope příkazem using a otevře první připojení, které ho automaticky zařadí do TransactionScope. Transakce je původně zařazena jako jednoduchá transakce, nikoli úplná distribuovaná transakce. Kód předpokládá existenci podmíněné logiky (vynecháno pro stručnost). Otevře druhé připojení pouze v případě, že je to potřeba, zařazení do TransactionScope.

Při otevření připojení se transakce automaticky zvýší na úplnou distribuovanou transakci. Kód pak vyvolá TransactionScope.Complete, který potvrdí transakci. Kód odstraní dvě připojení při ukončení příkazů using pro připojení. Metoda TransactionScope.Dispose pro TransactionScope se automaticky volá při ukončení bloku using pro TransactionScope. Pokud byla v jakémkoli okamžiku v bloku TransactionScope vyvolána výjimka, Complete se nevolá a distribuovaná transakce se vrátí zpět při odstranění TransactionScope.

using (TransactionScope transScope = new TransactionScope())
{
    using (SqlConnection connection1 = new
       SqlConnection(connectString1))
    {
        // Opening connection1 automatically enlists it in the
        // TransactionScope as a lightweight transaction.
        connection1.Open();

        // Do work in the first connection.

        // Assumes conditional logic in place where the second
        // connection will only be opened as needed.
        using (SqlConnection connection2 = new
            SqlConnection(connectString2))
        {
            // Open the second connection, which enlists the
            // second connection and promotes the transaction to
            // a full distributed transaction.
            connection2.Open();

            // Do work in the second connection.
        }
    }
    //  The Complete method commits the transaction.
    transScope.Complete();
}