Partager via


Utiliser System.Transactions

S'applique à :SQL Server

L’espace de noms System.Transactions fournit une infrastructure de transaction entièrement intégrée à ADO.NET et à l’intégration du CLR (Common Language Runtime) SQL Server. La classe System.Transactions.TransactionScope effectue un bloc de code transactionnel en inscrivant implicitement des connexions dans une transaction distribuée. Vous devez appeler la méthode Complete à la fin du bloc de code marqué par le TransactionScope. La méthode Dispose est appelée lorsque l’exécution du programme laisse un bloc de code, ce qui entraîne l’arrêt de la transaction si la méthode Complete n’est pas appelée. Si une exception a été levée qui entraîne la suppression du code dans l’étendue, la transaction est considérée comme abandonnée.

Nous vous recommandons d’utiliser un bloc using pour vous assurer que la méthode Dispose est appelée sur l’objet TransactionScope lorsque le bloc using est arrêté. L’échec de validation ou de restauration des transactions en attente peut dégrader sérieusement les performances, car le délai d’attente par défaut pour l'TransactionScope est d’une minute. Si vous n’utilisez pas d’instruction using, vous devez effectuer tout le travail dans un bloc Try et appeler explicitement la méthode Dispose dans le bloc Finally.

Si une exception se produit dans le TransactionScope, la transaction est marquée comme incohérente et abandonnée. Elle est rétablie lorsque la TransactionScope est supprimée. Si aucune exception ne se produit, les transactions sont validées.

TransactionScope ne doit être utilisé que lorsque des sources de données locales et distantes ou des gestionnaires de ressources externes sont accessibles, car TransactionScope provoque toujours la promotion des transactions, même si elles sont utilisées uniquement dans une connexion contextuelle.

La classe TransactionScope crée une transaction avec un System.Transactions.Transaction.IsolationLevel de Serializable par défaut. Selon votre application, vous pouvez envisager de baisser le niveau d'isolation pour éviter une contention élevée au sein de votre application.

Remarque

Nous vous recommandons de n'effectuer que des mises à jour, des insertions et des suppressions dans les transactions distribuées sur des serveurs distants parce qu'ils consomment d'importantes ressources de base de données. Si l’opération sera effectuée sur le serveur local, une transaction distribuée n’est pas nécessaire et une transaction locale suffit. SELECT instructions peuvent verrouiller inutilement les ressources de base de données et, dans certains scénarios, il peut être nécessaire d’utiliser des transactions pour les sélections. Tout travail autre que celui sur une base de données doit être exécuté en dehors de la portée de la transaction, à moins qu'il n'implique d'autres gestionnaires de ressources transactionnels.

Bien qu’une exception dans l’étendue de la transaction empêche la validation de la transaction, la classe TransactionScope n’a pas de provision pour restaurer les modifications apportées à votre code en dehors de l’étendue de la transaction elle-même. Si vous devez effectuer une action lorsque la transaction est restaurée, vous devez écrire votre propre implémentation de l’interface System.Transactions.IEnlistmentNotification et inscrire explicitement la transaction.

Exemples

Pour utiliser System.Transactions, vous devez avoir une référence au fichier System.Transactions.dll.

Le code suivant montre comment créer une transaction qui peut être promue sur deux instances différentes de SQL Server. Ces instances sont représentées par deux objets System.Data.SqlClient.SqlConnection différents, qui sont encapsulés dans un bloc TransactionScope. Le code crée le bloc TransactionScope avec une instruction using et ouvre la première connexion, qui l’inscrit automatiquement dans le TransactionScope. La transaction est inscrite initialement comme transaction légère, et non comme transaction distribuée complète. Le code suppose l’existence d’une logique conditionnelle (omise pour la concision). Elle ouvre la deuxième connexion uniquement si nécessaire, en l’inscrivant dans le TransactionScope.

Lorsque la connexion est ouverte, la transaction est automatiquement promue en transaction distribuée complète. Le code appelle ensuite TransactionScope.Complete, qui valide la transaction. Le code supprime les deux connexions lors de la sortie des instructions using pour les connexions. La méthode TransactionScope.Dispose de l'TransactionScope est automatiquement appelée à l’arrêt du bloc using pour le TransactionScope. Si une exception a été levée à un moment quelconque dans le bloc TransactionScope, Complete n’est pas appelé et la transaction distribuée est rétablie lorsque le TransactionScope est supprimé.

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