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

WCF 交易傳播完整指南:配置、模式與程式設計模型

     編輯:關於.NET

前言

交易是建構可靠服務應用程式的關鍵。WCF 提供聲明式交易支援,允許跨服務邊界傳播交易,讓多個服務操作在單一不可分割的交易中完成。本文詳細說明交易流配置、傳播模式與程式設計模型。

交易流配置

交易感知繫結

僅下列繫結支援交易流:

  • NetTcpBinding
  • NetNamedPipeBinding
  • WSHttpBinding
  • WSDualHttpBinding
  • WSFederationHttpBinding

預設 TransactionFlow = false,需在服務端與客戶端雙方啟用:

<bindings>
  <netTcpBinding>
    <binding name="TransactionalTCP" transactionFlow="true" />
  </netTcpBinding>
</bindings>

注意:TransactionFlow 不會發布至中繼資料,客戶端設定檔需手動啟用。

作業合約與交易流選項

[ServiceContract]
interface IMyContract
{
    [OperationContract]
    [TransactionFlow(TransactionFlowOption.Allowed)]
    void MyMethod(...);
}

public enum TransactionFlowOption
{
    NotAllowed,  // 預設:禁止傳播
    Allowed,     // 允許:客戶端有交易則傳播
    Mandatory    // 強制:必須傳播,且繫結必須啟用交易流
}

三種選項比較

選項客戶端無交易客戶端有交易繫結需求
NotAllowed服務建立新交易或無交易忽略客戶端交易任意繫結
Allowed服務建立新交易或無交易使用客戶端交易客戶端/服務繫結相容即可
Mandatory擲回例外使用客戶端交易雙方必須用交易感知繫結並啟用 TransactionFlow

限制:單向作業 (IsOneWay=true) 不得設為 Allowed/Mandatory,因無回應訊息無法回滾。

環境交易

System.Transactions.Transaction.Current 取得目前執行緒的環境交易。特性:

  • 儲存於 TLS,呼叫鏈上所有物件共享
  • WCF 資源管理員(SQL Server 等)自動登記於環境交易
  • 本地交易提升為分散式交易由 DTC 管理
  • 兩個識別碼:LocalIdentifier(永不為 null)、DistributedIdentifier(未提升時為 Guid.Empty)

服務交易程式設計模型

預設服務作業無環境交易。需以 OperationBehaviorAttribute.TransactionScopeRequired 宣告:

class MyService : IMyContract
{
    [OperationBehavior(TransactionScopeRequired = true)]
    public void MyMethod()
    {
        Transaction tx = Transaction.Current;
        Debug.Assert(tx != null);  // 保證有交易
    }
}

交易來源決策邏輯

  1. 若客戶端交易被傳播 → 成為環境交易
  2. 否則 → WCF 建立新交易作為環境交易

八種有效配置排列與四種傳播模式

由三個雙值/三值選項組合:繫結流程、合約流程選項、作業範圍需求。

模式繫結流程合約選項範圍需求行為推薦配置
Client/ServiceTrueAllowedTrue優先用客戶端交易,否則自建Allowed + ScopeRequired=true
ClientTrueMandatoryTrue必須用客戶端交易Mandatory + ScopeRequired=true
ServiceFalse/TrueNotAllowedTrue永遠自建新交易無流程屬性 + ScopeRequired=true
None任意任意False無環境交易ScopeRequired=false (預設)

四種模式適用場景

1. Client/Service 模式(最推薦)

  • 服務可獨立使用,也可併入客戶端交易
  • 最大化一致性,減少死結風險(資源登記同一交易)
  • 斷言:Transaction.Current != null(不確定是客戶端還是本地交易)

2. Client 模式

  • 服務設計上必須在客戶端交易內執行,不可獨立
  • 避免死結、最大化一致性
  • 斷言:DistributedIdentifier != Guid.Empty(確為分散式交易)

3. Service 模式

  • 服務需在客戶端交易外執行交易性工作(如日誌、稽核、事件發布)
  • 即使客戶端回滾,服務工作仍保留
  • 風險:可能損害一致性(一個提交一個回滾)
  • 適用:日誌服務、稽核服務
  • 斷言:DistributedIdentifier == Guid.Empty(本地交易)

4. None 模式

  • 作業最好有交易但非必要,失敗不應回滾客戶端交易
  • 例如:列印回條(缺紙不應回滾轉帳)
  • 危險:服務變更不會隨客戶端回滾而復原
  • 對策:客戶端捕獲 None 模式服務的例外,避免干擾自身交易

投票與完成

OperationBehaviorAttribute.TransactionAutoComplete(預設 true)控制自動投票:

  • 無未處理例外 → 投票 Commit
  • 有未處理例外 → 投票 Abort
  • 僅有 Session 服務可設為 false

交易完成時機

  • 根作業(TransactionScopeRequired=true 且無傳入交易)完成時,交易結束
  • 下游服務只能投票,無法完成交易
  • 非服務客戶端用 TransactionScope 建立根交易:
using (var scope = new TransactionScope())
using (var proxy1 = new MyContractClient())
using (var proxy2 = new MyOtherContractClient())
{
    proxy1.MyMethod(...);
    proxy2.MyOtherMethod(...);
    scope.Complete();  // 提交交易
}

總結

WCF 交易支援強大且簡單:透過少量屬性設定選擇邏輯傳播模式。核心決策在於「服務是否應共享客戶端交易」與「服務是否需獨立交易」。理解四種模式權衡,能設計出既可靠又具彈性的分散式系統。

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