.NET Framework 類別庫
TransactionScope 類別

注意:這個類別是 .NET Framework 2.0 版的新功能。

使程式碼區塊可交易。這個類別無法被繼承。

命名空間: System.Transactions
組件: System.Transactions (在 system.transactions.dll 中)

語法

Visual Basic (宣告)
Public NotInheritable Class TransactionScope
    Implements IDisposable
Visual Basic (使用方式)
Dim instance As TransactionScope
C#
public sealed class TransactionScope : IDisposable
C++
public ref class TransactionScope sealed : IDisposable
J#
public final class TransactionScope implements IDisposable
JScript
public final class TransactionScope implements IDisposable
備註

System.Transactions 基礎結構同時提供根據 Transaction 類別的明確程式撰寫模型 (Programming Model),以及使用 TransactionScope 類別的隱含程式撰寫模型,而在此類別中,交易會自動由基礎結構來管理。

Note重要資訊:

建議您使用 TransactionScope 類別建立隱含交易,如此可自動為您管理環境交易內容。如果是需要跨多個函式呼叫或多個執行緒呼叫來使用相同交易的應用程式,您也應該使用 TransactionScopeDependentTransaction 類別。如需這個模型的詳細資訊,請參閱使用交易範圍實作隱含交易主題。如需撰寫交易式應用程式的詳細資訊,請參閱撰寫交易應用程式

new 陳述式執行個體化 TransactionScope 時,交易管理員會決定要參與哪個交易,一旦決定後,範圍永遠會參與該交易。此決策是根據兩個因素而定:環境交易是否存在,以及建構函式 (Constructor) 中的 TransactionScopeOption 參數值。環境交易是在其中執行您的程式碼之交易,您可以藉由呼叫 Transaction 類別的靜態 (Static) Current 屬性,取得環境交易的參考。如需如何使用這個參數的詳細資訊,請參閱使用交易範圍實作隱含交易主題的<交易流程管理>一節。

如果沒有任何例外狀況 (Exception) 在交易範圍中發生 (也就是,在 TransactionScope 物件的初始化與呼叫其 Dispose 方法之間),則會允許範圍所參與的交易繼續。如果有例外狀況在交易範圍內發生,則會復原範圍所參與的交易。

當您的應用程式完成所有要在交易中執行的工作後,您應該只呼叫 Complete 方法一次,以通知交易管理員可以接受認可交易。無法呼叫這個方法會使交易中止。

Dispose 方法的呼叫會標記交易範圍的結尾,在呼叫這個方法後發生的例外狀況不太可能會影響交易。

如果您修改範圍內部的 Current 值,則當呼叫 Dispose 時會擲回例外狀況。不過,在範圍的結尾會還原先前的值。此外,如果您在建立交易的交易範圍內部,於 Current 上呼叫 Dispose,則交易會在範圍的結尾中止。

範例

下列範例示範了如何使用 TransactionScope 類別,定義要參與交易的程式碼區塊。

Visual Basic
'  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
C#
// 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
執行緒安全

這個型別對多執行緒作業而言是安全的。

平台

Windows 98、 Windows 2000 SP4、 Windows Millennium Edition、 Windows Server 2003、 Windows XP Media Center Edition、 Windows XP Professional x64 Edition、 Windows XP SP2、 Windows XP Starter Edition

.NET Framework 並不支援各種平台的所有版本。如需支援平台版本的相關資訊,請參閱系統需求一節的內容。

版本資訊

.NET Framework

支援版本:2.0
請參閱

標記 :


Page view tracker