Transactions locales (ADO.NET)

Mise à jour : November 2007

Dans ADO.NET, vous pouvez utiliser des transactions lorsque vous souhaitez lier plusieurs tâches entre elles afin qu'elles s'exécutent comme une seule unité de travail. Par exemple, imaginez qu'une application exécute 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 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 lorsqu'il s'agit d'une transaction en une seule phase et qu'elle est gérée directement par la base de données. Les transactions sont considérées comme distribuées lorsqu'elles sont coordonnées par un moniteur de transaction et utilisent des mécanismes de prévention de défaillance (tels qu'une validation en deux phases) pour la résolution des transactions.

Chacun des fournisseurs de données .NET Framework a son propre objet Transaction pour l'exécution des transactions locales. Si vous avez besoin qu'une transaction soit effectuée dans une base de données SQL Server, sélectionnez une transaction System.Data.SqlClient. Pour une transaction Oracle, utilisez le fournisseur System.Data.OracleClient. En outre, il y a une nouvelle classe DbTransaction disponible pour l'écriture de code indépendant du fournisseur qui requiert des transactions.

Remarque :

Les transactions ont une efficacité maximale lorsqu'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. Pour plus d'informations sur l'exécution de transactions côté serveur, consultez la documentation en ligne de SQL Server.

Exécution d'une transaction à l'aide d'une connexion unique

Dans ADO.NET, vous contrôlez les transactions à l'aide de 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.

Remarque :

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 2005 AdventureWorks, qui sont validées si aucune exception n'est levée. Le code dans le bloc catch annule la transaction si une exception est levée. 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.

  1. 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.

  2. 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'objet Transaction n'a pas été affecté à la propriété Transaction de l'objet Command, une exception est levée.

  3. Exécutez les commandes requises.

  4. 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 utilisant ADO.NET avec Microsoft SQL Server.

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
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);
        }
    }
}

Voir aussi

Concepts

Transactions distribuées (ADO.NET)

Intégration de System.Transactions à SQL Server (ADO.NET)

Autres ressources

Transactions et concurrence (ADO.NET)