本機交易 (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 區塊中的程式碼便會復原交易。如果交易在完成之前遭到中止或連接關閉,則會自動復原該交易。
範例
請遵循下列步驟來執行交易。
呼叫 SqlConnection 物件的 BeginTransaction 方法,來標記交易的開始。BeginTransaction 方法會將參考傳回給交易。此參考會指派給登記在交易中的 SqlCommand 物件。
將 Transaction 物件指派給要執行之 SqlCommand 的 Transaction 屬性。如果在有交易正在作用中的連接上執行命令,且 Transaction 物件尚未指派給 Command 物件的 Transaction 屬性,便會擲回例外狀況。
執行必要的命令。
呼叫 SqlTransaction 物件的 Commit 方法來完成交易,或呼叫 Rollback 方法來中止交易。如果在執行 Commit 或 Rollback 方法之前關閉或處置連接,則會復原交易。
下列程式碼範例會藉由搭配使用 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);
}
}
}
請參閱
概念
與 SQL Server 進行 System.Transactions 整合 (ADO.NET)