整體來講,WCF開發人員不須要涉及事務協議與管理器。咱們應該依賴WCF來選擇相應的事務協議和管理器,重點關注業務邏輯的實現。編程
WCF是根據事務範圍裏的參與個體來選擇事務管理協議的。事務管理協議之間的差異與遠程調用、通行協議,以及跨越的系統邊界有關。跨域
可選擇的管理協議以下:網絡
輕量級事務協議
這個協議只在本地同一個應用程序域內的上下文環境裏管理事務,他不能跨越應用程序邊界來傳播事務(更不能跨越進程或機器邊界了),也不能跨越服務邊界(從客戶端到服務段)。輕量級協議只能在單個服務內部或同一個應用程序域裏的兩個個體間使用。與其它協議相比,輕量級協議擁有最佳的性能。分佈式
OleTx事務協議
這個協議能夠跨域應用程序域、進程和機器邊界來傳播事務,而且能夠管理兩階段提交協議。協議使用RPC調用,而且消息格式是Windows指定的二進制格式。由於這個緣由,他不能跨越防火牆,也不能與非Windows平臺的系統交互。這一般不能問題所在,應爲OleTx進程用於Intranet裏,並且是相同的Windows環境下。性能
WSAT事務協議
這個協議和OleTx事務協議同樣,能夠跨域應用程序域、進程和機器邊界來傳播事務,而且能夠管理兩階段提交協議。可是,WSAT事務協議基於行業標準,並可以穿越防火牆。推薦在Internet上有多個事務管理器參與事務時使用這種協議。優化
沒有綁定支持輕量級事務協議,由於該協議沒法跨域服務邊界傳播。TCP和IPC綁定能夠配置爲同時使用OleTx和WSAT事務協議,或者使用二者之一。兩個綁定默認使用OlxTx事務協議,在須要的時候會切換爲WSAT事務協議。spa
此外,這些Intranet綁定容許使用配置文件或代碼來配置事務協議,這一點和其它的綁定屬性一致。設計
WCF提供了抽象類TransactionProtocol,定義以下:代理
// 指定在流動事務中使用的事務處理協議。 public abstract class TransactionProtocol { // 初始化 System.ServiceModel.TransactionProtocol 類的新實例。 protected TransactionProtocol(); // 獲取事務處理協議的默認值。 public static TransactionProtocol Default { get; } // 獲取 OleTransactions 事務處理協議值。 public static TransactionProtocol OleTransactions { get; } // 獲取 WSAtomicTransaction11 事務處理協議值。 public static TransactionProtocol WSAtomicTransaction11 { get; } // 獲取 WSAtomicTransactionOctober2004 事務處理協議值。 public static TransactionProtocol WSAtomicTransactionOctober2004 { get; } }TCP和IPC都提供了TransactionProtocol屬性。例如:code
public class NetTcpBinding : Binding,... { TransactionProtocal TransactionProtocal { get; set } ...... }
採用編程方式設置協議,首先須要構建須要的綁定類型,而後使用某個靜態方法來設置屬性:
NetTcpBinding bingding = new NetTcpBinding(); //支持傳播事務的協議 bingding.TransactionFlow = true; bingding.TransactionProtocol = TransactionProtocol.WSAtomicTransactionOctober2004;注意,事務協議配置只有在啓用事務傳播的時候纔有意義。配置文件裏配置事務協議以下:
當爲TCP和IPC綁定配置事務協議時,服務和客戶端必須使用相同的協議。因爲TCP和IPC綁定只能在Intranet內部使用,所以配置爲WSAT事務協議並沒什麼實際意義。
WS綁定(WsSHttpBinding、WS2007HttpBinding、WSDualHttpBinding等等)都是爲了Internet設計的,當須要多個事務管理器協調工做時,就應該使用WSAT事務協議。可是,當Internet只有一個事務管理器時,這些綁定默認都使用OleTx事務協議。這裏不必配置特別的事務協議。
若是管理事務呢?最佳的解決方案就是使用一個名叫事務管理器的第三方來完成這個工做,由它來負責爲客戶端和服務端兩個兩階段提交協議。
事務管理器是整個事務控制模型的核心和樞紐,是它控制着事務的全部參與者,協調整個事務從開始到完成的全部相關處理流程。事務管理器爲應用和資源管理器提供一系列核心的事務性的服務,實現事務的開始、提交和回滾。Windows提供了三種不一樣的事務管理器,以下圖所示:
上圖所示的三個事務管理器就是輕量級事務管理器(LTM),核心事務管理器(KTM)和分佈式事務、協調器(DTC)。做爲平臺使用的功能、應用程序要作的工做、調用的服務、使用的資源,.NET都會自動分配合適的事務管理器。由於分配工做是自動完成的,因此代碼就看能夠從事務管理和事務協議之間解耦了。再次重申,開發人員歷來不須要爲事務管理器煩惱。
輕量級事務管理器(LTM: Lightweight Transaction Manager)
正如其名稱隱含的意思,輕量級事務管理器(如下簡稱LTM)具備最小的負載,是性能最高的事務管理器。
LTM的做用範圍僅限於開啓事務的應用程序域(AppDomain)中,而且登記到事務中的持久化資源(Durable Resource)數量不能超過一個。
通常地,被開啓的事務就由LTM管理,若是事務涉及到跨應用程序域的操做,當前的事務回被奉送、傳播到另外一個執行上下文中,此時事務將脫離LTM的管轄。
此外,基於LTM的事務中能夠同時登記(Enlist)多個易失型資源(Volatile),可是僅僅容許登記惟一一個持久化資源。當第二個持久化資源被登記到當前事務中,該事務也將脫離LTM的管轄。
若是隻有單個資源管理器,而且資源支持單階段提交協議,LTM會使用優化協議。更爲重要的是,LTM只能管理單個服務內的事務,不支持事務流傳播。
LTM是最小的事務管理器,它能夠直接在資源上執行事務操做。
內核事務管理器(KTM:Kernel transaction Manager)
內核事務管理器(如下簡稱KTM)在Windows Vista中被引入,並被用於後續的Windows Server 2008和Windows 7。引入KTM的主要的目的在於實現將文件管理和註冊表管理歸入事務的範疇。藉助於KTM,咱們能夠以事務的方式操做NTFS文件系統下的文件資源,以及註冊表資源。咱們將支持事務的文件系統和註冊表成爲事務型的文件系統(TxF)和事務型註冊表(TxR)。
之因此被稱爲內核事務管理器,使由於基於KTM的事務控制引擎運行在內核模式(Kernel Mode),而不是用戶模式(User Mode)下。
KTM在內存中調用時使用輕量級事務協議。KTM之多能夠管理一個持久化的內核資源管理器(KTM)事務,可是能夠管理多個易失型事務資源管理器。
使用KTM時至多可使用一個服務,但不是傳播事務。
分佈式事務協調器(DTC:Distributed Transaction Coordinator)
DTC用於管理跨邊界(跨應用程序域、進程、機器以致跨網絡)執行的分佈式事務,它採用相應的事務管理協議,好比OleTx和WSAT,協調一個分佈式事務中的全部參與者。
在事務流跨越服務邊界時,會使用DTC做爲事務管理器,它能夠管理包含多個服務和資源管理器的事務。
在每臺容許WCF的機器上,DTC默認都是可用的,WCF緊密的與DTC繼承在一塊兒。他負責建立事務,收集資源管理器投票,以及告訴資源管理器提交或終止事務。
以下圖所示,該應用程序爲一個非事務性客戶端調用機器A上的服務。機器A上的服務被配置來使用一個事務。這個服務會成爲事務的根(root),它不只能夠啓動事務,也能夠決定何時結束事務。
WCF中每一個事務只多有一個根服務,這是由於非事務性客戶端也能夠做爲服務的根。
當機器A事務中的某個服務嘗試訪問機器B中的資源或服務時,他應該有一個遠程服務的代理,這個代理能夠傳播事務ID到機器B。機器B的攔截器能夠獲取事務ID,而後通知機器B上的DTC來啓動並管理本地事務。由於事務ID已經傳播給機器B,因此機器B上的資源管理器能夠自動加載這個事務ID。與之相似,事務ID也會傳播到機器C。
當事務完成時,若是全部的參與者投票提交事務,此時就會啓動兩階段提交協議。根機器上的DTC會收集全部的投票,並通知參與事務的全部機器上的DTC,告訴它們啓動第一階段協議。遠程機器上的DTC收集本身機器上全部資源管理器的投票結果並告訴DTC。在全部遠程機器都返回結果之後,根機器上的DTC綜合全部資源管理器的投票結果。若是全部的資源管理器都投票提交,根機器上的DTC會通知遠程上的全部的DTC來啓動第二階段協議,而後通知各個資源管理器提交事務。若是一個資源管理器投票終止事務,那麼根機器上的DTC就會通知全部的DTC終止事務。注意,只有根事務上的DTC纔有權利收集投票結果並作出決策。
.NET能夠動態地給事務管理器分配事務。若是事務管理器沒法勝任工做,.NET將會提高事務,也就是讓更高級別的事務管理器來管理事務。一個事務能夠被提高多個一旦提高就沒法降級。由於能夠動態提高,因此開發人員避免了直接與事務管理器打交道。
LTM提高
.NET裏的每一個事務都是有LTM着手管理的。只有事務只與單個持久化資源交互,並且事務不嘗試傳播事務到WCF服務,LTM就能代碼最佳的性能。LTM還能夠管理易失型資源管理器,可是,若是事務嘗試加入第二個持久化資源或者傳播事務給其它服務,.NET將會從LTM提高到DTC。若是第一個持久化事務被KTM訪問,.NET將會把事務從LTM提高到KTM。
KTM提高
只要與單個內核資源管理器(LRM)交互且事務是本地的,KTM就能夠管理事務。KTM能夠在須要時管理儘量多的易失型資源管理器。若是事務嘗試加入第二個持久化資源或者傳播事務給其它服務,.NET將會從KTM提高到DTC。