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 TransactionScope
je 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.IsolationLevel
Serializable
. 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
.
-
jazyka C#
jazyka C# - visual basic .NET
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();
}