Lokale transacties
Transacties in ADO.NET worden gebruikt wanneer u meerdere taken aan elkaar wilt koppelen, zodat ze worden uitgevoerd als één werkeenheid. Stel dat een toepassing twee taken uitvoert. Eerst wordt een tabel bijgewerkt met ordergegevens. Ten tweede wordt een tabel bijgewerkt die inventarisgegevens bevat, waarbij de bestelde items worden gedebiteerd. Als een van beide taken mislukt, worden beide updates teruggedraaid.
Het transactietype bepalen
Een transactie wordt beschouwd als een lokale transactie wanneer het een transactie met één fase is en rechtstreeks door de database wordt verwerkt. Een transactie wordt beschouwd als een gedistribueerde transactie wanneer deze wordt gecoördineerd door een transactiemonitor en gebruikmaakt van fail-safe mechanismen (zoals doorvoeren in twee fasen) voor transactieomzetting.
Elk van de .NET Framework-gegevensproviders heeft een eigen Transaction
object voor het uitvoeren van lokale transacties. Als u een transactie wilt uitvoeren in een SQL Server-database, selecteert u een System.Data.SqlClient transactie. Gebruik de System.Data.OracleClient provider voor een Oracle-transactie. Daarnaast is er een DbTransaction klasse beschikbaar voor het schrijven van provideronafhankelijke code waarvoor transacties zijn vereist.
Notitie
Transacties zijn het meest efficiënt wanneer ze op de server worden uitgevoerd. Als u werkt met een SQL Server-database die uitgebreid gebruik maakt van expliciete transacties, kunt u overwegen deze als opgeslagen procedures te schrijven met behulp van de Transact-SQL BEGIN TRANSACTION-instructie.
Een transactie uitvoeren met één Verbinding maken ion
In ADO.NET bepaalt u transacties met het Connection
object. U kunt een lokale transactie initiëren met de BeginTransaction
methode. Zodra u een transactie hebt gestart, kunt u een opdracht in die transactie inschakelen met de Transaction
eigenschap van een Command
object. Vervolgens kunt u wijzigingen doorvoeren of terugdraaien die zijn aangebracht in de gegevensbron op basis van het slagen of mislukken van de onderdelen van de transactie.
Notitie
De EnlistDistributedTransaction
methode mag niet worden gebruikt voor een lokale transactie.
Het bereik van de transactie is beperkt tot de verbinding. In het volgende voorbeeld wordt een expliciete transactie uitgevoerd die bestaat uit twee afzonderlijke opdrachten in het try
blok. Met de opdrachten worden INSERT-instructies uitgevoerd voor de tabel Production.ScrapReason in de voorbeelddatabase AdventureWorks SQL Server, die worden doorgevoerd als er geen uitzonderingen worden gegenereerd. Met de code in het catch
blok wordt de transactie teruggedraaid als er een uitzondering wordt gegenereerd. Als de transactie is afgebroken of de verbinding wordt gesloten voordat de transactie is voltooid, wordt deze automatisch teruggedraaid.
Opmerking
Volg deze stappen om een transactie uit te voeren.
Roep de BeginTransaction methode van het SqlConnection object aan om het begin van de transactie te markeren. De BeginTransaction methode retourneert een verwijzing naar de transactie. Deze verwijzing wordt toegewezen aan de SqlCommand objecten die zijn opgenomen in de transactie.
Wijs het
Transaction
object toe aan de eigenschap van de Transaction SqlCommand te uitvoeren eigenschap. Als een opdracht wordt uitgevoerd op een verbinding met een actieve transactie en hetTransaction
object niet is toegewezen aan deTransaction
eigenschap van hetCommand
object, wordt er een uitzondering gegenereerd.Voer de vereiste opdrachten uit.
Roep de Commit methode van het SqlTransaction object aan om de transactie te voltooien of roep de Rollback methode aan om de transactie te beëindigen. Als de verbinding is gesloten of verwijderd voordat de Commit of Rollback methoden zijn uitgevoerd, wordt de transactie teruggedraaid.
In het volgende codevoorbeeld ziet u transactionele logica met behulp van ADO.NET met Microsoft SQL Server.
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