在 WF 4.0 中,TransactionScope 是實現資料庫交易控制的核心活動。本文將透過完整範例,詳細說明如何使用 TransactionScope 管理交易、處理例外、設定隔離層級,以及自訂具備 Rollback 功能的活動。
首先建立名為 wxwinterWFTest 的資料庫,並在其中建立 UserTable 資料表:
CREATE TABLE UserTable (
UserID NVARCHAR(50) PRIMARY KEY
);

建立 insertDataToSQLServerActivity,用於向資料表插入記錄:
public sealed class insertDataToSQLServerActivity : NativeActivity
{
public InArgument<string> UserID { get; set; }
protected override void Execute(NativeActivityContext context)
{
insertUserTable(UserID.Get(context));
}
void insertUserTable(string UserID)
{
using (var con = new System.Data.SqlClient.SqlConnection(
"Data Source=.;Initial Catalog=wxwinterWFTest;Integrated Security=True;"))
{
con.Open();
using (var cmd = con.CreateCommand())
{
cmd.CommandText = string.Format("insert into UserTable (UserID) values ('{0}')", UserID);
cmd.ExecuteNonQuery();
}
}
}
}
| 屬性 | 類型 | 說明 |
|---|---|---|
| Body | Activity | 要在交易中執行的活動 |
| Timeout | InArgument<TimeSpan> | 交易過期時間 |
| AbortInstanceOnTransactionFailure | bool | 交易失敗時是否中止工作流執行個體 |
| IsolationLevel | System.Transactions.IsolationLevel | 交易隔離層級 |

TransactionScope,設定 AbortInstanceOnTransactionFailure = falseinsertDataToSQLServerActivity,分別插入 "wxd"、"wxwinter"、"wxd"(第三筆會因主鍵重複拋出例外)
static void workflowCompleted(WorkflowApplicationCompletedEventArgs e)
{
Console.WriteLine("完成,狀態:{0}", e.CompletionState);
}
static void aborted(WorkflowApplicationAbortedEventArgs e)
{
Console.WriteLine("aborted,Reason:{0}", e.Reason.Message);
}
static UnhandledExceptionAction unhandledException(WorkflowApplicationUnhandledExceptionEventArgs e)
{
Console.WriteLine("unhandledException:{0}", e.UnhandledException.Message);
return UnhandledExceptionAction.Abort;
}
static void transactionScopeWorkflow()
{
var instance = new WorkflowApplication(new TransactionScopeWorkflow());
instance.Completed = workflowCompleted;
instance.OnUnhandledException = unhandledException;
instance.Aborted = aborted;
instance.Run();
}
因主鍵重複導致交易失敗,觸發 OnUnhandledException,工作流狀態為 Faulted。前兩筆資料已回滾,資料表保持空白。

設定為 true 時,交易失敗會直接觸發 Aborted 事件,不會經過 OnUnhandledException。工作流狀態為 Canceled。

AbortInstanceOnTransactionFailure 設定不一致,false 的層級會觸發 OnUnhandledExceptiontrue,內層逾時小於外層時,工作流會取消並觸發 AbortedTerminateWorkflow 終止流程透過 RuntimeTransactionHandle 取得目前交易並手動呼叫 Rollback():
public sealed class rollbackTransactionActivity : NativeActivity
{
public InArgument<string> Text { get; set; }
protected override void Execute(NativeActivityContext context)
{
var handle = new RuntimeTransactionHandle();
handle = context.Properties.Find(handle.ExecutionPropertyName) as RuntimeTransactionHandle;
var transaction = handle.GetCurrentTransaction(context);
Console.WriteLine("LocalIdentifier:{0}", transaction.TransactionInformation.LocalIdentifier);
Console.WriteLine("CreationTime:{0}", transaction.TransactionInformation.CreationTime);
Console.WriteLine("Status:{0}", transaction.TransactionInformation.Status);
Console.WriteLine("IsolationLevel:{0}", transaction.IsolationLevel);
transaction.TransactionCompleted += (s, e) => Console.WriteLine("TransactionCompleted");
transaction.Rollback(new Exception("wxwinter 手動回滾事務"));
}
}

| 層級 | 說明 |
|---|---|
| ReadUncommitted | 允許髒讀,不發布共享鎖 |
| ReadCommitted | 預設值,避免髒讀,但可能不可重複讀 |
| RepeatableRead | 鎖定查詢範圍資料,防止不可重複讀 |
| Serializable | 最高層級,範圍鎖定防止幻影讀 |
| Snapshot | 透過版本控制減少阻塞 |
