Transactions locales
S'applique à : .NET Framework .NET .NET Standard
Les transactions dans ADO.NET servent à lier plusieurs tâches ensemble de sorte qu’elles s’exécutent comme une seule unité de travail. Par exemple, imaginez qu'une application effectue deux tâches. Premièrement, elle met à jour une table avec des informations de commande. Deuxièmement, elle met à jour une table qui contient des informations de stock, en débitant les articles commandés. Si l’une ou l’autre des tâches échoue, les deux mises à jour sont annulées.
Détermination du type de transaction
Une transaction est considérée comme locale quand il s’agit d’une transaction monophase et qu’elle est gérée directement par la base de données. Une transaction est considérée comme étant distribuée quand elle est coordonnée par un moniteur de transaction et qu’elle utilise des mécanismes de prévention de défaillance (tels qu’une validation en deux phases) pour sa résolution.
Le fournisseur de données Microsoft SqlClient pour SQL Server dispose de son propre objet SqlTransaction pour effectuer des transactions locales dans des bases de données SQL Server. D’autres fournisseurs de données .NET fournissent également leurs propres objets Transaction
. Par ailleurs, il existe une classe DbTransaction qui permet d’écrire du code indépendant du fournisseur qui exige des transactions.
Notes
Les transactions ont une efficacité maximale quand elles sont exécutées sur le serveur. Si vous utilisez une base de données SQL Server qui utilise beaucoup des transactions explicites, envisagez de les écrire sous la forme de procédures stockées à l’aide de l’instruction Transact-SQL BEGIN TRANSACTION.
Exécution d’une transaction avec une seule connexion
Dans ADO.NET, vous contrôlez les transactions avec l’objet Connection
. Vous pouvez initier une transaction locale avec la méthode BeginTransaction
. Après avoir commencé une transaction, vous pouvez inscrire une commande dans cette transaction avec la propriété Transaction
d’un objet Command
. Vous pouvez ensuite valider ou annuler les modifications apportées à la source de données en fonction de la réussite ou de l’échec des composants de la transaction.
Notes
La méthode EnlistDistributedTransaction
ne doit pas être utilisée pour une transaction locale.
La portée de la transaction est limitée à la connexion. L’exemple suivant exécute une transaction explicite consistant en deux commandes distinctes dans le bloc try
. Les commandes exécutent des instructions INSERT sur la table Production.ScrapReason
dans l’exemple de base de données SQL Server AdventureWorks, qui sont validées si aucune exception n’est levée. Le code dans le bloc catch
annule la transaction en cas d'exception. En cas d'annulation de la transaction ou de fermeture de la connexion avant que la transaction ne soit terminée, celle-ci est automatiquement annulée.
Exemple
Procédez comme suit pour effectuer une transaction.
Appelez la méthode BeginTransaction de l’objet SqlConnection pour marquer le début de la transaction. La méthode BeginTransaction retourne une référence à la transaction. Cette référence est affectée aux objets SqlCommand inscrits dans la transaction.
Assignez l'objet
Transaction
à la propriété Transaction de l'objet SqlCommand à exécuter. Si une commande est exécutée sur une connexion sur laquelle une transaction est active et si l’objetTransaction
n’a pas été affecté à la propriétéTransaction
de l’objetCommand
, une exception est levée.Exécutez les commandes requises.
Appelez la méthode Commit de l'objet SqlTransaction pour effectuer la transaction ou la méthode Rollback pour y mettre fin. Si la connexion est fermée ou libérée avant que l’une des méthodes Commit ou Rollback ait été exécutée, la transaction est annulée.
L’exemple de code suivant illustre la logique transactionnelle en utilisant le fournisseur de données Microsoft SqlClient pour SQL Server.
using System;
using Microsoft.Data.SqlClient;
class Program
{
static void Main(string[] args)
{
string connectionString = "Data Source = localhost; Integrated Security = true; Initial Catalog = AdventureWorks";
using (SqlConnection connection = new SqlConnection(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);
}
}
}
}
}