Místní transakce
Transakce v ADO.NET se používají, když chcete svázat více úkolů dohromady, aby se spouštěly jako jedna jednotka práce. Představte si například, že aplikace provede dvě úlohy. Nejprve aktualizuje tabulku s informacemi o objednávce. Za druhé aktualizuje tabulku, která obsahuje informace o inventáři a inkasuje objednané položky. Pokud některý z úkolů selže, vrátí se obě aktualizace zpět.
Určení typu transakce
Transakce se považuje za místní transakci, pokud se jedná o jednofázovou transakci a zpracovává ji přímo databáze. Transakce se považuje za distribuovanou transakci, když je koordinovaná monitorováním transakcí a používá mechanismy bezpečné pro selhání (například dvoufázové potvrzení) pro řešení transakcí.
Každý z poskytovatelů dat rozhraní .NET Framework má svůj vlastní Transaction
objekt pro provádění místních transakcí. Pokud potřebujete provést transakci v databázi SQL Serveru, vyberte System.Data.SqlClient transakci. Pro transakci Oracle použijte System.Data.OracleClient poskytovatele. Kromě toho je DbTransaction k dispozici třída, která je k dispozici pro psaní kódu nezávislého na poskytovateli, který vyžaduje transakce.
Poznámka:
Transakce jsou nejúčinnější při provádění na serveru. Pokud pracujete s databází SQL Serveru, která provádí rozsáhlé využití explicitních transakcí, zvažte jejich zápis jako uložené procedury pomocí příkazu Transact-SQL BEGIN TRANSACTION.
Provedení transakce pomocí jediného Připojení ionu
V ADO.NET řídíte transakce s objektem Connection
. S metodou BeginTransaction
můžete zahájit místní transakci. Jakmile začnete transakci, můžete do této transakce zahrnout příkaz s Transaction
vlastností objektu Command
. Změny provedené ve zdroji dat pak můžete potvrdit nebo vrátit zpět na základě úspěchu nebo selhání komponent transakce.
Poznámka:
Metoda EnlistDistributedTransaction
by neměla být použita pro místní transakci.
Rozsah transakce je omezen na připojení. Následující příklad provádí explicitní transakci, která se skládá ze dvou samostatných příkazů v try
bloku. Příkazy spouštějí příkazy INSERT proti tabulce Production.ScrapReason v ukázkové databázi AdventureWorks SQL Serveru, které jsou potvrzeny, pokud nejsou vyvolány žádné výjimky. Kód v catch
bloku vrátí transakce zpět, pokud je vyvolán výjimka. Pokud je transakce přerušena nebo je připojení uzavřeno před dokončením transakce, automaticky se vrátí zpět.
Příklad
K provedení transakce použijte tento postup.
BeginTransaction Volání metody objektu SqlConnection označit začátek transakce. Metoda BeginTransaction vrátí odkaz na transakci. Tento odkaz je přiřazen k SqlCommand objektům, které jsou zařazeny do transakce.
Transaction
Přiřaďte objekt vlastnostiTransaction, která SqlCommand se má provést. Pokud je příkaz proveden na připojení s aktivní transakcí aTransaction
objekt nebyl přiřazen kTransaction
vlastnosti objektuCommand
, je vyvolána výjimka.Spusťte požadované příkazy.
Commit Volání metody objektu SqlTransaction k dokončení transakce, nebo volání Rollback metody pro ukončení transakce. Pokud je připojení uzavřeno nebo uvolněno před provedením Commit nebo Rollback metody, transakce se vrátí zpět.
Následující příklad kódu ukazuje transakční logiku pomocí ADO.NET s Microsoft SQL Serverem.
using (SqlConnection connection = new(connectionString))
{
connection.Open();
// Start a local transaction.
SqlTransaction sqlTran = connection.BeginTransaction();
// Enlist a command in the current transaction.
SqlCommand command = connection.CreateCommand();
command.Transaction = sqlTran;
try
{
// Execute two separate commands.
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')";
command.ExecuteNonQuery();
command.CommandText =
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')";
command.ExecuteNonQuery();
// Commit the transaction.
sqlTran.Commit();
Console.WriteLine("Both records were written to database.");
}
catch (Exception ex)
{
// Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message);
try
{
// Attempt to roll back the transaction.
sqlTran.Rollback();
}
catch (Exception exRollback)
{
// Throws an InvalidOperationException if the connection
// is closed or the transaction has already been rolled
// back on the server.
Console.WriteLine(exRollback.Message);
}
}
}
Using connection As New SqlConnection(connectionString)
connection.Open()
' Start a local transaction.
Dim sqlTran As SqlTransaction = connection.BeginTransaction()
' Enlist a command in the current transaction.
Dim command As SqlCommand = connection.CreateCommand()
command.Transaction = sqlTran
Try
' Execute two separate commands.
command.CommandText = _
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong size')"
command.ExecuteNonQuery()
command.CommandText = _
"INSERT INTO Production.ScrapReason(Name) VALUES('Wrong color')"
command.ExecuteNonQuery()
' Commit the transaction
sqlTran.Commit()
Console.WriteLine("Both records were written to database.")
Catch ex As Exception
' Handle the exception if the transaction fails to commit.
Console.WriteLine(ex.Message)
Try
' Attempt to roll back the transaction.
sqlTran.Rollback()
Catch exRollback As Exception
' Throws an InvalidOperationException if the connection
' is closed or the transaction has already been rolled
' back on the server.
Console.WriteLine(exRollback.Message)
End Try
End Try
End Using