雖然WCF負責事務傳播及兩階段提交協議的管理工做,可是 她不知道事務是否應該提交或終止。這須要根服務告訴WCF應該什麼時候啓動兩階段提交協議、是提交仍是終止。WCF提供了兩種編程模式來對事務的結果進行投票,即聲明式和顯式模式。編程
聲明式投票
WCF能夠代替服務自動完成提交或終止事務的投票。自動投票是經過OpreationBehavior的TransactionAutoComplete屬性來控制的。ui
TransactionAutoComplete屬性的默認值爲true,能夠以下使用:spa
//服務端代碼必須置於服務中執行 [OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete=true)] public void CSMethod() { //獲取當前事務對象 Transaction transaction = Transaction.Current; }當這個屬性設置爲true時,若是操做裏沒有未處理的異常,則WCF將會自動提交事務。若是存在異常,WCF將會投票終止事務。注意,即便WCF必須經過捕獲異常來終止事務,它也是會從新拋出異常,以便異常沿着調用鏈傳播。設計
爲了依賴自動投票,必須把服務的TransactionScopeRequired 屬性設置爲true,由於自動投票只有在WCF爲服務設置了事務環境時纔有用。code
在TransactionScopeRequired設置爲true時,要儘可能避免捕獲和處理異常,顯式避免終止事務。對象
//服務端代碼必須置於服務中執行 [OperationBehavior(TransactionScopeRequired = true)] public void CSMethod() { try { ... } catch { Transactionn.Current.Rollback(); } }雖然服務捕獲了一次異常,但操做仍會引起異常,這是由於WCF會在客戶端拋出現像AbortedException同樣的異常。WCF是會這樣作 的,由於服務也許是包含多個服務、機器和站點事務的一部分。blog
明確投票
當TransactionAutoComplete設置爲false時,須要使用明確投票。事件
當禁止聲明式投票時,默認狀況下,不管是否發生異常,WCF將會自動終止全部的事務,你須要明確使用操做上下文的SetTransactionComplete()方法來提交事務。事務
public sealed class OperationContext : IExtensibleObject<OperationContext> { //...... // 摘要: // 提交當前正在執行的事務。 // // 異常: // System.InvalidOperationException: // 上下文中沒有任何事務。 public void SetTransactionComplete(); }確保在調用SetTransactionComplete()以後沒有再執行任何操做,特別是事務性工做。資源
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete=false)] public void CSMethod() { try { OperationContext.Current.SetTransactionComplete(); } catch (Exception) { throw; } }若是調用後嘗試執行任何事務性工做,即便訪問OperationContext.Current,WCF就會拋出相關的異常並終止事務。
明確投票是爲投票須要依賴其它信息(包括異常和錯誤)的狀況而設計的。可是,對於大部分應用程序與服務來講,應該選擇簡單的聲明式投票方式。
終止事務
事務什麼時候結束是由事務發起者決定的。根服務能夠調用其它服務並把事務傳播給它們。注意,下游服務只能使用對事務投票,不能提交完成事務。只有根事務能夠同時投票和提交完成事務。
當非事務型客戶端發起事務時,事務會在客戶銷燬事務對象時結束。
當事務試圖訪問其它事務佔有的資源管理器且須要佔用好久時可能會發生死鎖。爲了解決這個問題,事務必須可以在必定的超時事件(默認60s)內自動終止事務。一旦終止事務,任何傳播事務到服務的操做都會致使異常。
超時的服務行爲屬性,並且服務上的全部終結點的全部操做使用相同的超時事件。能夠經過ServiceBehaviorAttribute的TransactionTimeout屬性來設置超時時間。
例如,下面設計30s超時的代碼:
[ServiceBehavior(TransactionTimeout="00:00:30")] public class ClientServiceTransaction : IClientServiceTransaction {......}也能夠在宿主配置文件裏經過定義服務的自定義行爲來配置事務超時事件。
...... <behaviors> <serviceBehaviors> <behavior> <serviceMetadata httpGetEnabled="false" httpsGetEnabled="false"/> <serviceDebug includeExceptionDetailInFaults="true"/> <serviceTimeouts transactionTimeout="00:00:30"/> </behavior> </serviceBehaviors> </behaviors> ......以上事務超時的最大值爲10min。能夠經過機器配置文件來指定超過10分鐘的最大值,如40分鐘,如下是對machine.config的配置:
...... <system.transactions> <mechineSettings maxTimeout = "00:40:00"/> </system.transactions> ......