首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Windows Workflow Foundation 進階教學:第十五章 - 工作流與交易處理

     編輯:關於.NET

本章學習目標

  • 理解傳統交易模型 (XA/兩階段提交) 適用與不適用情境
  • 掌握補償式交易適用時機
  • 實作交易回滾與補償邏輯
  • 修改預設補償順序

交易處理核心概念

交易確保應用程式資料一致性:將多項作業視為單一工作單元,要么全成功要么全失敗。若中途失敗,系統需回到交易前的狀態。

ACID 特性

  • 原子性:全部完成或全部不執行。
  • 一致性:資料不違反完整性約束。
  • 隔離性:交易執行期間資料對其他交易不可見 (視隔離等級)。
  • 持久性:提交後資料永久保存,不怕系統故障。

傳統 XA 交易與長時間執行的衝突

XA 交易 (兩階段提交) 要求資源 (資料庫) 鎖定資料直到提交/回滾。若交易包含長時間人工作業 (如等待信用卡驗證),資料庫連接與鎖定將長時間佔用,嚴重影響並發與擴展性。網路環境下更不可行。

補償式交易

不鎖定資源,交易成功即提交;失敗時由應用程式執行「補償動作」抵銷已完成作業 (如已扣款則存回)。優點:資源無長時間鎖定、支援非交易資源 (Web 服務)。缺點:需自行撰寫補償邏輯,錯誤可能導致狀態更不一致。

WF 交易服務與活動

使用交易活動需啟用兩項服務:

  • SqlWorkflowPersistenceService (活動標記 PersistOnClose)
  • DefaultWorkflowTransactionService (負責交易啟動/提交)

TransactionScopeActivity (XA 風格)

  • 組合活動,內部活動自動參與環境交易 (Ambient Transaction)。
  • 成功自動提交,失敗自動回滾 (不拋出例外,靜默繼續)。
  • TransactionOptions 設定隔離等級 (預設 Serializable) 與逾時。
  • 不支援巢狀交易活動。

CompensatableTransactionScopeActivity (補償式)

  • 實作 ICompensatableActivity,提供補償處理常式。
  • 失敗時透過 ThrowActivity 觸發補償。
  • 補償處理常式中可放置 CompensateActivity 控制補償順序。
  • 支援傳統資料庫 (提交時同 XA) 及非交易資源 (Web 服務需自行實作補償通訊)。

CompensatableSequenceActivity

  • 可包含多個 CompensatableTransactionScope,將相關交易群組。
  • 子交易失敗時,父序列補償處理常式可透過 CompensateActivity 指定補償特定子活動或全部。
  • 可巢狀,但不能置於 CompensatableTransactionScope 內。

實作範例:ATM 應用程式

模擬自動櫃員機:存款使用 XA 交易 (TransactionScope),提款使用補償式交易 (CompensatableTransactionScope)。資料庫含帳號、PIN、餘額;預存程序強制在交易中執行 (檢查 @@TRANCOUNT)。

資料庫建立

  1. 執行 Create Woodgrove Database.sql 建立 Woodgrove (業務資料) 與 WorkflowStore (持久化) 兩個資料庫。
  2. 修改 App.config 連接字串。

加入 XA 交易 (存款)

  1. 開啟 Workflow1.cs 設計工具,進入 DepositState → CmdPressed4 分支。
  2. 拖曳 TransactionScopeActivity 置於 MakeDeposit (CodeActivity) 上方。
  3. 將 MakeDeposit 拖入 TransactionScope 內。
  4. 編譯測試:正常存款成功;勾選「Force Transactional Error」後存款失敗,餘額不變 (自動回滾)。

工作流設計檢視

插入 TransactionScope

MakeDeposit 置於 TransactionScope 內

加入補償式交易 (提款)

  1. 進入 WithdrawState → CmdPressed5 分支。
  2. 拖曳 CompensatableTransactionScopeActivity 包裹 MakeWithdrawal。
  3. 點擊智慧標籤選擇「檢視補償處理常式」。
  4. 加入 CodeActivity (CompensateWithdrawal):手動建立 SQL 交易呼叫 Deposit 預存程序存回提款金額。
  5. 加入 FailedActivity (錯誤訊息) 與 SetStateActivity (轉至 CompletedState)。

private void CompensateWithdrawal(object sender, EventArgs e)
{
    string connString = ConfigurationManager.ConnectionStrings["BankingDatabase"].ConnectionString;
    if (!String.IsNullOrEmpty(connString))
    {
        SqlConnection conn = null; SqlTransaction trans = null;
        try
        {
            conn = new SqlConnection(connString);
            SqlCommand cmd = new SqlCommand("dbo.Deposit", conn) { CommandType = CommandType.StoredProcedure };
            cmd.Parameters.Add(new SqlParameter("@AccountNo", SqlDbType.Int) { Value = _account });
            cmd.Parameters.Add(new SqlParameter("@ThrowError", SqlDbType.SmallInt) { Value = 0 });
            cmd.Parameters.Add(new SqlParameter("@Amount", SqlDbType.Money) { Value = CurrentMoneyValue });
            SqlParameter outParm = new SqlParameter("@Balance", SqlDbType.Money) { Direction = ParameterDirection.Output };
            cmd.Parameters.Add(outParm);
            conn.Open();
            trans = conn.BeginTransaction();
            cmd.Transaction = trans;
            cmd.ExecuteNonQuery();
            trans.Commit();
            CurrentBalance = (decimal)outParm.Value;
        }
        catch { if (trans != null) trans.Rollback(); }
        finally { if (conn != null) conn.Close(); }
    }
}

智慧標籤選擇補償處理常式

補償處理常式設計檢視

加入 Failed 與 SetState

測試結果

  • 正常提款:餘額扣減。
  • 勾選錯誤選項提款:MakeWithdrawal 實際成功扣款,但隨後觸發補償存回,最終餘額不變。

補償順序控制

  • 預設:從最深層巢狀往外補償 (與完成順序相反)。
  • CompensateActivity 可在補償/取消/錯誤處理常式中指定 TargetActivityName,實現選擇性或自訂順序補償。
  • 若在父 CompensatableSequence 補償處理常式中呼叫 CompensateActivity 指定父活動,所有已成功的子活動皆會補償。

本章小結

WF 提供兩種交易模型:TransactionScope 適合短時資料庫操作;CompensatableTransactionScope 適合長時間流程或非交易資源。補償邏輯需謹慎設計,確保能正確逆向已完成作業。透過 CompensatableSequence 與 CompensateActivity 可精確控制複雜業務流程的補償行為。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved