Remarque : cette classe est nouvelle dans le .NET Framework version 2.0.
Rend un bloc de code transactionnel. Cette classe ne peut pas être héritée.
Espace de noms : System.Transactions
Assembly : System.Transactions (dans system.transactions.dll)
Visual Basic (Déclaration)
Public NotInheritable Class TransactionScope
Implements IDisposable
Visual Basic (Utilisation)
Dim instance As TransactionScope
public sealed class TransactionScope : IDisposable
public ref class TransactionScope sealed : IDisposable
public final class TransactionScope implements IDisposable
public final class TransactionScope implements IDisposable
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.
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.
Public Function CreateTransactionScope( _
ByVal connectString1 As String, ByVal connectString2 As String, _
ByVal commandText1 As String, ByVal commandText2 As String) As Integer
' Initialize the return value to zero and create a StringWriter to display results.
Dim returnValue As Integer = 0
Dim writer As System.IO.StringWriter = 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 scope As New TransactionScope()
Using connection1 As 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.
Dim command1 As SqlCommand = 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 connection2 As 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
Dim command2 As SqlCommand = New SqlCommand(commandText2, connection2)
returnValue = command2.ExecuteNonQuery()
writer.WriteLine("Rows to be affected by command2: {0}", returnValue)
Catch ex As Exception
' Display information that command2 failed.
writer.WriteLine("returnValue for command2: {0}", returnValue)
writer.WriteLine("Exception Message2: {0}", ex.Message)
End Try
End Using
Catch ex As Exception
' Display information that command1 failed.
writer.WriteLine("returnValue for command1: {0}", returnValue)
writer.WriteLine("Exception Message1: {0}", ex.Message)
End Try
End Using
' The Complete method commits the transaction. If an exception has been thrown,
' Complete is called and the transaction is rolled back.
scope.Complete()
End Using
' The returnValue is greater than 0 if the transaction committed.
If returnValue > 0 Then
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.")
End If
' Display messages.
Console.WriteLine(writer.ToString())
Return returnValue
End Function
// 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;
}
System.Object
System.Transactions.TransactionScope
Ce type est sécurisé pour les opérations multithread.
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.
.NET Framework
Prise en charge dans : 2.0