TransactionScope, classe
Assembly : System.Transactions (dans system.transactions.dll)
L'infrastructure System.Transactions fournit à la fois un modèle de programmation explicite basé sur la classe Transaction et un modèle de programmation implicite à l'aide de la classe TransactionScope dans laquelle les transactions sont gérées automatiquement par l'infrastructure.
Important : |
|---|
| Il est recommandé de créer des transactions implicites à l'aide de la classe TransactionScope afin que le contexte de la transaction ambiante soit géré automatiquement. Vous devez également utiliser la classe TransactionScope et DependentTransaction pour les applications qui requièrent l'utilisation de la même transaction pour plusieurs appels de fonction ou plusieurs appels de thread. Pour plus d'informations sur ce modèle, consultez la rubrique Implémentation d'une transaction implicite à l'aide de la portée de transaction. Pour plus d'informations sur l'écriture d'une application transactionnelle, consultez Écriture d'une application de transaction. |
Sur une instanciation d'un TransactionScope par l'instruction new, le gestionnaire de transactions détermine à quelle transaction participer. Une fois déterminée, la portée participe toujours à cette transaction. La décision est basée sur deux facteurs : la présence d'une transaction ambiante et la valeur du paramètre TransactionScopeOption dans le constructeur. La transaction ambiante est la transaction dans laquelle votre code s'exécute. Vous pouvez obtenir une référence à la transaction ambiante en appelant la propriété Current statique de la classe Transaction. Pour plus d'informations sur la façon dont ce paramètre est utilisé, consultez la section « Gestion du flux de transaction » dans la rubrique Implémentation d'une transaction implicite à l'aide de la portée de transaction.
Si aucune exception ne se produit dans la portée de transaction (c'est-à-dire entre l'initialisation de l'objet TransactionScope et l'appel à sa méthode Dispose), la transaction à laquelle la portée participe est autorisée à continuer. Si une exception se produit dans la portée de la transaction, la transaction à laquelle elle participe sera restaurée.
Lorsque votre application termine tout le travail qu'elle souhaite exécuter dans une transaction, vous devez appeler la méthode Complete une fois seulement pour informer ce gestionnaire de transactions qu'il est acceptable de valider la transaction. Ne pas appeler cette méthode entraîne l'abandon de la transaction.
Un appel à la méthode Dispose marque la fin de la portée de transaction. Les exceptions qui se produisent après avoir appelé cette méthode peuvent ne pas affecter la transaction.
Si vous modifiez la valeur de Current à l'intérieur d'une portée, une exception est levée lorsque Dispose est appelé. Toutefois, la valeur précédente est restaurée à la fin de la portée. De plus, si vous appelez Dispose sur Current à l'intérieur d'une portée de transaction qui a créé la transaction, la transaction est abandonnée à la fin de la portée.
L'exemple suivant montre comment utiliser la classe TransactionScope pour définir un bloc de code en vue de participer à une transaction.
// This function takes arguments for 2 connection strings and commands to create a transaction // involving two SQL Servers. It returns a value > 0 if the transaction is committed, 0 if the // transaction is rolled back. To test this code, you can connect to two different databases // on the same server by altering the connection string, or to another RDBMS such as Oracle // by altering the code in the connection2 code block. static public int CreateTransactionScope( string connectString1, string connectString2, string commandText1, string commandText2) { // Initialize the return value to zero and create a StringWriter to display results. int returnValue = 0; System.IO.StringWriter writer = new System.IO.StringWriter(); // Create the TransactionScope to execute the commands, guaranteeing // that both commands can commit or roll back as a single unit of work. using (TransactionScope scope = new TransactionScope()) { using (SqlConnection connection1 = new SqlConnection(connectString1)) { try { // Opening the connection automatically enlists it in the // TransactionScope as a lightweight transaction. connection1.Open(); // Create the SqlCommand object and execute the first command. SqlCommand command1 = new SqlCommand(commandText1, connection1); returnValue = command1.ExecuteNonQuery(); writer.WriteLine("Rows to be affected by command1: {0}", returnValue); // If you get here, this means that command1 succeeded. By nesting // the using block for connection2 inside that of connection1, you // conserve server and network resources as connection2 is opened // only when there is a chance that the transaction can commit. using (SqlConnection connection2 = new SqlConnection(connectString2)) try { // The transaction is escalated to a full distributed // transaction when connection2 is opened. connection2.Open(); // Execute the second command in the second database. returnValue = 0; SqlCommand command2 = new SqlCommand(commandText2, connection2); returnValue = command2.ExecuteNonQuery(); writer.WriteLine("Rows to be affected by command2: {0}", returnValue); } catch (Exception ex) { // Display information that command2 failed. writer.WriteLine("returnValue for command2: {0}", returnValue); writer.WriteLine("Exception Message2: {0}", ex.Message); } } catch (Exception ex) { // Display information that command1 failed. writer.WriteLine("returnValue for command1: {0}", returnValue); writer.WriteLine("Exception Message1: {0}", ex.Message); } } // The Complete method commits the transaction. If an exception has been thrown, // Complete is not called and the transaction is rolled back. scope.Complete(); } // The returnValue is greater than 0 if the transaction committed. if (returnValue > 0) { writer.WriteLine("Transaction was committed."); } else { // You could write additional business logic here, for example, you can notify the caller // by throwing a TransactionAbortedException, or logging the failure. writer.WriteLine("Transaction rolled back."); } // Display messages. Console.WriteLine(writer.ToString()); return returnValue; }
Windows 98, Windows 2000 SP4, Windows Millennium Edition, Windows Server 2003, Windows XP Édition Media Center, Windows XP Professionnel Édition x64, Windows XP SP2, Windows XP Starter Edition
Le .NET Framework ne prend pas en charge toutes les versions de chaque plate-forme. Pour obtenir la liste des versions prises en charge, consultez Configuration requise.
Important :