WCF能夠跨越服務邊界傳遞事務。這可讓服務參與到客戶端事務裏,客戶端還能夠在同一個事務裏調用多個服務。客戶端自己不必定是WCF服務。客戶端事務是否傳播到服務端能夠經過綁定和操做契約契約的設置來控制。ui
咱們把可以支持客戶端事務傳播給服務端的綁定稱爲「事務感知」型綁定。spa
只有TCP、IPC和WS綁定支持事務傳播。設計
默認狀況下,事務感知型綁定並不會傳播事務。服務宿主或管理員必須明確設置服務接收進入的跨越組織或業務邊界的事務。code
爲了支持事務傳播。就必須在服務端和客戶端綁定上明確設置容許傳播事務。對象
全部的事務感知型綁定都提供了一個布爾型Transactionlow屬性:blog
public class NetTcpBinding : Binding, IBindingRuntimePreferences { // 若是啓用事務流,則爲 true;不然爲 false。默認值爲 false。 [DefaultValue(false)] public bool TransactionFlow { get; set; } // ...... }爲了啓用事務傳播,只需將屬性設置爲true便可。能夠經過代碼或配置文件進行設置。對於TCP綁定,以下:事務
代碼:get
NetTcpBinding binding=new NetTcpBinding(); binding.TransactionFlow=true;配置文件:io
<netTcpBinding> <binding transactionFlow="true" /> </netTcpBinding>嚴格來講,事務不須要啓用可靠消息。事務會依賴本身的機制實現可靠性。可是,啓用可靠性會下降事務中斷的可能性,它會盡可能保證通訊可靠,這意味着事務不大可能由於通訊問題而中斷。所以,最佳作法就是在NetTcpBinding和WsHttpBinding支持事務的時候,啓用可靠性傳輸。class
<netTcpBinding> <binding transactionFlow="true"> <reliableSession enabled="true"/> </binding> </netTcpBinding>
使用事務感知型綁定並啓用事務流,並不意味着服務想在每一個操做裏使用客戶端事務或客戶端讓事務優先傳播。
這種服務級別的決策應該是客戶端 與服務端之間協商約定的一部分。所以,WCF提供了TransactionFlowAttribute屬性,它能夠控制客戶端事務是否傳播給服務端。
public sealed class TransactionFlowAttribute : Attribute, IOperationBehavior { public TransactionFlowAttribute(TransactionFlowOption transactions); // 一個 System.ServiceModel.TransactionFlowOption,指示是否支持傳入事務。 public TransactionFlowOption Transactions { get; } }public enum TransactionFlowOption { // 事務不該成爲流。這是默認值。 NotAllowed = 0, // 事務能夠成爲流。 Allowed = 1, // 事務必須成爲流。 Mandatory = 2, }注意,TransactionFlow屬性標記在方法層級上,由於WCF堅持事務流應該在操做級別決定,而不是在服務級別決定:
public class MyService : IMyService { [TransactionFlow(TransactionFlowOption.Allowed)] public void MyMethod() { } }這是爲了達到方法級別參與客戶端事務的粒度而精心設計的。
TransactionFlow屬性會包含在服務發佈的元數據中,因此當你引用服務契約定義時,定義將會包含這個TransactionFlow值。WCF將會讓你在服務端實現的操做時上應用TransactionFlow屬性:
[ServiceContract] public interface IMyService { [OperationContract] void MyMethod(); } public class MyService : IMyService { [TransactionFlow(TransactionFlowOption.Allowed)] public void MyMethod() { } }可是,這種用法並不值得鼓勵,由於它會分割即將發佈的邏輯服務契約定義代碼。
TransactionFlowOption.NotAllowed
禁止參與事務。
當操做配置爲禁止傳播事務流時,客戶端不能傳播到服務端。即便客戶端發起一個事務且綁定容許傳播,服務也會忽略事務流。服務永遠不會使用客戶端事務,且服務和客戶端能夠選擇任意綁定並使用任意配置。TransactionFlowOption.NotAllowed是TransactionFlowOption的默認值。
TransactionFlowOption.Allowed
容許參與事務,若是調用方啓用了事務,則參與。
當操做配置爲容許傳播事務時,若是客戶端包含事務,服務將容許跨越邊界傳播客戶端事務。可是,即便客戶端傳播了事務,服務也不必定必須使用這個事務。當使用TransactionFlowOption.Allowed時,服務能夠配置使用任意綁定。不管是否爲事務感知型綁定均可以,可是客戶端與服務端綁定配置要兼容。當服務端綁定配置了容許事務流時,客戶端能夠傳播也能夠不傳播事務。
TransactionFlowOption.Mandatory
強制參與事務,調用方必須啓用事務才能調用本服務。
當操做配置爲TransactionFlowOption.Mandatory時,服務和客戶端必須使用事務感知型綁定,並啓用事務傳播。WCF會在服務加載是校驗這些設置。對於強制事務流,客戶端事務會一致傳播給服務。可是 ,服務能夠選擇參與或不參與客戶端事務。
ServiceBehaviorAttribute
描述服務參與事務的一些參數。
- TransactionAutoCompleteOnSessionClose = bool:指示當會話(Session)結束時是否自動提交事務(Complete); 這個屬性和服務對象實例模式緊密相關,使用的時候,應該着重當心。
- ReleaseServiceInstanceOnTransactionComplete = bool:指示事務提交後是否釋放服務實例對象;
TransactionIsolationLevel= System.Transactions.IsolationLevel:用於指示事務隔離級別。- OperationBehaviorAttribute:描述契約方法如何參與事務的一些參數
- TransactionScopeRequired = bool:該屬性是 WCF 分佈事務所必需的。它代表服務方法必須在事務範圍(transaction scope)內執行。若是不添加該標記,則意味着服務方法不參與到事務中。
- TransactionAutoComplete = bool: 指示方法正常結束後是否自動提交事務。
客戶端能夠傳播事務到 服務端,固然也容許服務端根據須要終止客戶端。可是,在單調操做中,客戶端沒法傳遞事務流到客戶端,由於調用消息不包含應答消息。
[ServiceContract] public interface IMyService { [OperationContract(IsOneWay=true)] [TransactionFlow(TransactionFlowOption.Allowed)] //錯誤操做 void MyMethod(); }