共用方式為


本機交易 (ADO.NET)

更新: November 2007

當您要將多個工作繫結在一起,以讓它們當做單一的工作單位來執行時,便會使用 ADO.NET 中的交易。例如,假設應用程式執行兩項工作。首先,它會更新包含訂單資訊的資料表。然後會更新包含存貨資訊的資料表,將訂購項目記入借方。如果其中任何一項作業失敗,則兩個更新作業都會復原。

決定交易類型

當交易為單一階段,且直接由資料庫處理時,系統便會將該交易視為本機交易。當交易由交易監視器進行協調,並使用保全機制 (如兩階段認可) 進行交易解析時,系統便會將該交易視為分散式交易。

每個 .NET Framework 資料提供者都有它自己的 Transaction 物件,以執行本機交易。如果您需要在 SQL Server 資料庫中執行交易,請選取 System.Data.SqlClient 交易。若為 Oracle 交易,請使用 System.Data.OracleClient 提供者。此外,新 DbTransaction 類別可用於寫入獨立於提供者以外且需要交易的程式碼。

注意事項:

在伺服器上執行交易是最有效率的。如果您使用的 SQL Server 資料庫大量使用明確的交易,請考慮使用 Transact-SQL BEGIN TRANSACTION 陳述式,將它們寫入為預存程序。如需執行伺服器端交易的詳細資訊,請參閱《SQL Server 線上叢書》。

使用單一連接執行交易

在 ADO.NET 中,您會使用 Connection 物件控制交易。您可使用 BeginTransaction 方法來起始本機交易。開始交易之後,您可使用 Command 物件的 Transaction 屬性,在該交易中登記命令。然後,您可根據交易元件的成敗,來認可或復原對資料來源所做的修改。

注意事項:

EnlistDistributedTransaction 方法不可用於本機交易。

交易的範圍僅限於連接。下列範例執行由 try 區塊中的兩個單獨命令所組成的明確交易。這些命令會針對 AdventureWorks SQL Server 2005 範例資料庫中的 Production.ScrapReason 資料表執行 INSERT 陳述式,如果未擲回例外狀況,該陳述式便會得到認可。如果擲回例外狀況,則 catch 區塊中的程式碼便會復原交易。如果交易在完成之前遭到中止或連接關閉,則會自動復原該交易。

範例

請遵循下列步驟來執行交易。

  1. 呼叫 SqlConnection 物件的 BeginTransaction 方法,來標記交易的開始。BeginTransaction 方法會將參考傳回給交易。此參考會指派給登記在交易中的 SqlCommand 物件。

  2. 將 Transaction 物件指派給要執行之 SqlCommandTransaction 屬性。如果在有交易正在作用中的連接上執行命令,且 Transaction 物件尚未指派給 Command 物件的 Transaction 屬性,便會擲回例外狀況。

  3. 執行必要的命令。

  4. 呼叫 SqlTransaction 物件的 Commit 方法來完成交易,或呼叫 Rollback 方法來中止交易。如果在執行 CommitRollback 方法之前關閉或處置連接,則會復原交易。

下列程式碼範例會藉由搭配使用 ADO.NET 與 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);
        }
    }
}

請參閱

概念

分散式交易 (ADO.NET)

與 SQL Server 進行 System.Transactions 整合 (ADO.NET)

其他資源

交易和並行 (ADO.NET)