[索引頁]
[源碼下載]?
作者:webabcd
介紹
WCF(Windows Communication Foundation) - 事務(Transaction):
??? ·對契約方法使用TransactionFlowAttribute聲明(設置TransactionFlowOption參數),以指定服務操作的事務流策略
??? ·對服務方法是用OperationBehaviorAttribute聲明(設置TransactionScopeRequired參數),以指定方法是否在事務范圍(TransactionScope)內執行
??? ·配置host和client的binding節點的transactionFlow屬性,以指定綁定是否支持流事務
示例
1、服務
Hello.cs
using?System;?
using?System.Collections.Generic;?
using?System.Linq;?
using?System.Text;?
?
using?System.ServiceModel;?
?
namespace?WCF.ServiceLib.Transaction?
{?
????????/// <summary>?
????????///?IHello接口?
????????/// </summary>?
????????[ServiceContract]?
????????public?interface?IHello?
????????{?
????????????????/// <summary>?
????????????????///?打招呼方法?
????????????????/// </summary>?
????????????????/// <param name="name">人名</param>?
????????????????/// <remarks>?
????????????????/// TransactionFlow - 指定服務操作是否愿意接受來自客戶端的傳入事務?
????????????????/// NotAllowed - 禁止事務。默認值?
????????????????/// Allowed - 允許事務?
????????????????/// Mandatory - 強制事務?
????????????????///?</remarks>?
????????????????/// <returns></returns>?
????????????????[OperationContract]?
????????????????[TransactionFlow(TransactionFlowOption.Mandatory)]?
????????????????void?WriteHello(string?name);?
????????}?
?
????????/// <summary>?
????????///?Hello類?
????????/// </summary>?
????????public?class?Hello : IHello?
????????{?
????????????????/// <summary>?
????????????????///?打招呼方法?
????????????????/// </summary>?
????????????????/// <param name="name">人名</param>?
????????????????/// <remarks>?
????????????????/// OperationBehavior - 指定服務方法的本地執行行為?
????????????????/// 1、TransactionScopeRequired - 如果方法需要事務范圍才能執行,則為?true;否則為?false。默認值為false?
????????????????/// 將 TransactionScopeRequired 設置為?true,可以要求操作在事務范圍內執行。如果流事務可用,則操作會在該事務內執行。如果流事務不可用,則會創建一個新事務并使用它來執行操作?
????????????????/// 2、TransactionAutoComplete - 默認值為?true?
????????????????///?true?- 當方法完成執行時,將把該事務標志為完成(自動提交事務)?
????????????????///?false?- 需要調用OperationContext.Current.SetTransactionComplete()方法來手工配置該事務的正確完成;否則,該事務將被標志為失敗(手動提交事務)?
????????????????///?</remarks>?
????????????????/// <returns></returns>?
????????????????[OperationBehavior(TransactionScopeRequired =?true, TransactionAutoComplete =?true)]?
????????????????public?void?WriteHello(string?name)?
????????????????{?
????????????????????????DBDataContext ctx =?new?DBDataContext();?
?
????????????????????????ctx.Items.InsertOnSubmit(?
????????????????????????????????new?Item?
????????????????????????????????{?
????????????????????????????????????????Title =?string.Format("Hello: {0}, TransactionId: {1}", name, System.Transactions.Transaction.Current.TransactionInformation.LocalIdentifier),?
????????????????????????????????????????CreatedTime = DateTime.Now?
????????????????????????????????});?
?
????????????????????????ctx.SubmitChanges();?
????????????????}?
????????}?
}
using?System;?
using?System.Collections.Generic;?
using?System.Linq;?
using?System.Text;?
?
using?System.ServiceModel;?
?
namespace?WCF.ServiceLib.Transaction?
{?
????????/// <summary>?
????????///?IHi接口?
????????/// </summary>?
????????[ServiceContract]?
????????public?interface?IHi?
????????{?
????????????????/// <summary>?
????????????????///?打招呼方法?
????????????????/// </summary>?
????????????????/// <param name="name">人名</param>?
????????????????/// <returns></returns>?
????????????????[OperationContract]?
????????????????[TransactionFlow(TransactionFlowOption.Mandatory)]?
????????????????void?WriteHi(string?name);?
????????}?
?
????????/// <summary>?
????????///?Hi類?
????????/// </summary>?
????????public?class?Hi : IHi?
????????{?
????????????????/// <summary>?
????????????????///?打招呼方法?
????????????????/// </summary>?
????????????????/// <param name="name">人名</param>?
????????????????/// <returns></returns>?
????????????????[OperationBehavior(TransactionScopeRequired =?true, TransactionAutoComplete =?true)]?
????????????????public?void?WriteHi(string?name)?
????????????????{?
????????????????????????if?(DateTime.Now.Second % 2 == 0)?
????????????????????????????????throw?new?System.Exception("為測試事務而拋出的異常");?
?
????????????????????????DBDataContext ctx =?new?DBDataContext();?
?
????????????????????????ctx.Items.InsertOnSubmit(?
????????????????????????????????new?Item?
????????????????????????????????{?
????????????????????????????????????????Title =?string.Format("Hi: {0}, TransactionId: {1}", name, System.Transactions.Transaction.Current.TransactionInformation.LocalIdentifier),?
????????????????????????????????????????CreatedTime = DateTime.Now?
????????????????????????????????});?
?
????????????????????????ctx.SubmitChanges();?
????????????????}?
????????}?
}
using?System;?
using?System.Collections.Generic;?
using?System.Linq;?
using?System.Text;?
?
using?System.ServiceModel;?
?
namespace?WCF.ServiceLib.Transaction?
{?
????????/// <summary>?
????????///?結果接口?
????????/// </summary>?
????????[ServiceContract]?
????????public?interface?IResult?
????????{?
????????????????[OperationContract]?
????????????????List<Item> GetResult();?
????????}?
?
????????/// <summary>?
????????///?結果類?
????????/// </summary>?
????????public?class?Result : IResult?
????????{?
????????????????/// <summary>?
????????????????///?返回數據庫結果?
????????????????/// </summary>?
????????????????/// <returns></returns>?
????????????????public?List<Item> GetResult()?
????????????????{?
????????????????????????DBDataContext ctx =?new?DBDataContext();?
?
????????????????????????var result = from l?in?ctx.Items?
???????????????????????????????????????????????? orderby l.CreatedTime descending?
???????????????????????????????????????????????? select l;?
?
????????????????????????return?result.ToList();?
????????????????}?
????????}?
}
2、宿主
Hello.svc
using?System;?
using?System.Collections;?
using?System.Configuration;?
using?System.Data;?
using?System.Linq;?
using?System.Web;?
using?System.Web.Security;?
using?System.Web.UI;?
using?System.Web.UI.HtmlControls;?
using?System.Web.UI.WebControls;?
using?System.Web.UI.WebControls.WebParts;?
using?System.Xml.Linq;?
?
using?System.Threading;?
?
public?partial?class?Transaction_Sample : System.Web.UI.Page?
{?
????????protected?void?Page_Load(object?sender, EventArgs e)?
????????{?
?
????????}?
?
????????protected?void?btnSubmit_Click(object?sender, EventArgs e)?
????????{?
????????????????var proxyHello =?new?TransactionSvc.Hello.HelloClient();?
????????????????var proxyHi =?new?TransactionSvc.Hi.HiClient();?
????????????????var proxyResult =?new?TransactionSvc.Result.ResultClient();?
?
????????????????System.Transactions.TransactionOptions to =?new?System.Transactions.TransactionOptions();?
????????????????// 設置事務的超時時間?
????????????????to.Timeout =?new?TimeSpan(0, 0, 30);?
????????????????// 設置事務的隔離級別?
????????????????to.IsolationLevel = System.Transactions.IsolationLevel.Serializable;?
?
????????????????using?(var ts =?new?System.Transactions.TransactionScope())?
????????????????{?
????????????????????????try?
????????????????????????{?
????????????????????????????????proxyHello.WriteHello("webabcd");?
????????????????????????????????proxyHello.Close();?
?
????????????????????????????????proxyHi.WriteHi("webabcd");?
????????????????????????????????proxyHi.Close();?
?
????????????????????????????????ts.Complete();?
?
????????????????????????????????lblErr.Text =?"OK";?
????????????????????????}?
????????????????????????catch?(Exception ex)?
????????????????????????{?
????????????????????????????????lblErr.Text = ex.ToString();?
????????????????????????}?
????????????????}?
?
????????????????GridView1.DataSource = proxyResult.GetResult();?
????????????????GridView1.DataBind();?
????????????????proxyHello.Close();?
????????}?
}
[源碼下載]?
化零為整WCF(14) - 事務(Transaction)
作者:webabcd
介紹
WCF(Windows Communication Foundation) - 事務(Transaction):
??? ·對契約方法使用TransactionFlowAttribute聲明(設置TransactionFlowOption參數),以指定服務操作的事務流策略
??? ·對服務方法是用OperationBehaviorAttribute聲明(設置TransactionScopeRequired參數),以指定方法是否在事務范圍(TransactionScope)內執行
??? ·配置host和client的binding節點的transactionFlow屬性,以指定綁定是否支持流事務
示例
1、服務
Hello.cs

































































Hi.cs






















































Result.cs








































2、宿主
Hello.svc
<%@ ServiceHost Language="C#" Debug="true" Service="WCF.ServiceLib.Transaction.Hello" %>
Hi.svc
<%@ ServiceHost Language="C#" Debug="true" Service="WCF.ServiceLib.Transaction.Hi" %>
Result.svc
<%@ ServiceHost Language="C#" Debug="true" Service="WCF.ServiceLib.Transaction.Result" %>
Web.config
<?xml version="1.0"?>?
<configuration>?
????????<system.serviceModel>?
????????????????<behaviors>?
????????????????????????<serviceBehaviors>?
????????????????????????????????<behavior name="TransactionBehavior">?
????????????????????????????????????????<!--httpGetEnabled - 指示是否發布服務元數據以便使用 HTTP/GET 請求進行檢索,如果發布 WSDL,則為 true,否則為 false,默認值為 false-->?
????????????????????????????????????????<serviceMetadata httpGetEnabled="true" />?
????????????????????????????????????????<serviceDebug includeExceptionDetailInFaults="true"/>?
????????????????????????????????</behavior>?
????????????????????????</serviceBehaviors>?
????????????????</behaviors>?
????????????????<services>?
????????????????????????<!--name - 提供服務的類名-->?
????????????????????????<!--behaviorConfiguration - 指定相關的行為配置-->?
????????????????????????<service name="WCF.ServiceLib.Transaction.Hello" behaviorConfiguration="TransactionBehavior">?
????????????????????????????????<!--address - 服務地址-->?
????????????????????????????????<!--binding - 通信方式-->?
????????????????????????????????<!--contract - 服務契約-->?
????????????????????????????????<!--bindingConfiguration - 指定相關的綁定配置-->?
????????????????????????????????<endpoint address="" binding="wsHttpBinding" contract="WCF.ServiceLib.Transaction.IHello" bindingConfiguration="TransactionConfiguration" />?
????????????????????????</service>?
????????????????????????<service name="WCF.ServiceLib.Transaction.Hi" behaviorConfiguration="TransactionBehavior">?
????????????????????????????????<endpoint address="" binding="wsHttpBinding" contract="WCF.ServiceLib.Transaction.IHi" bindingConfiguration="TransactionConfiguration" />?
????????????????????????</service>?
????????????????????????<service name="WCF.ServiceLib.Transaction.Result" behaviorConfiguration="TransactionBehavior">?
????????????????????????????????<endpoint address="" binding="basicHttpBinding" contract="WCF.ServiceLib.Transaction.IResult" />?
????????????????????????</service>?
????????????????</services>?
????????????????<bindings>?
????????????????????????<wsHttpBinding>?
????????????????????????????????<!--transactionFlow - 指定該綁定是否應支持流事務-->?
????????????????????????????????<binding name="TransactionConfiguration" transactionFlow="true" />?
????????????????????????</wsHttpBinding>?
????????????????</bindings>?
????????</system.serviceModel>?
</configuration>
<configuration>?
????????<system.serviceModel>?
????????????????<behaviors>?
????????????????????????<serviceBehaviors>?
????????????????????????????????<behavior name="TransactionBehavior">?
????????????????????????????????????????<!--httpGetEnabled - 指示是否發布服務元數據以便使用 HTTP/GET 請求進行檢索,如果發布 WSDL,則為 true,否則為 false,默認值為 false-->?
????????????????????????????????????????<serviceMetadata httpGetEnabled="true" />?
????????????????????????????????????????<serviceDebug includeExceptionDetailInFaults="true"/>?
????????????????????????????????</behavior>?
????????????????????????</serviceBehaviors>?
????????????????</behaviors>?
????????????????<services>?
????????????????????????<!--name - 提供服務的類名-->?
????????????????????????<!--behaviorConfiguration - 指定相關的行為配置-->?
????????????????????????<service name="WCF.ServiceLib.Transaction.Hello" behaviorConfiguration="TransactionBehavior">?
????????????????????????????????<!--address - 服務地址-->?
????????????????????????????????<!--binding - 通信方式-->?
????????????????????????????????<!--contract - 服務契約-->?
????????????????????????????????<!--bindingConfiguration - 指定相關的綁定配置-->?
????????????????????????????????<endpoint address="" binding="wsHttpBinding" contract="WCF.ServiceLib.Transaction.IHello" bindingConfiguration="TransactionConfiguration" />?
????????????????????????</service>?
????????????????????????<service name="WCF.ServiceLib.Transaction.Hi" behaviorConfiguration="TransactionBehavior">?
????????????????????????????????<endpoint address="" binding="wsHttpBinding" contract="WCF.ServiceLib.Transaction.IHi" bindingConfiguration="TransactionConfiguration" />?
????????????????????????</service>?
????????????????????????<service name="WCF.ServiceLib.Transaction.Result" behaviorConfiguration="TransactionBehavior">?
????????????????????????????????<endpoint address="" binding="basicHttpBinding" contract="WCF.ServiceLib.Transaction.IResult" />?
????????????????????????</service>?
????????????????</services>?
????????????????<bindings>?
????????????????????????<wsHttpBinding>?
????????????????????????????????<!--transactionFlow - 指定該綁定是否應支持流事務-->?
????????????????????????????????<binding name="TransactionConfiguration" transactionFlow="true" />?
????????????????????????</wsHttpBinding>?
????????????????</bindings>?
????????</system.serviceModel>?
</configuration>
3、客戶端
Sample.aspx
Sample.aspx
<%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="Sample.aspx.cs"?
????????Inherits="Transaction_Sample" Title="事務(Transaction)" %>?
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">?
</asp:Content>?
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">?
????????<p>?
????????????????<asp:Label ID="lblErr" runat="server" ForeColor="Red" />?
????????</p>?
????????<p>?
????????????????<asp:Button ID="btnSubmit" runat="server" Text="事務測試" OnClick="btnSubmit_Click" />?
????????????????<br />?
????????????????<br />?
????????????????<asp:GridView ID="GridView1" runat="server">?
????????????????</asp:GridView>?
????????</p>?
????????<p>?
????????????????2PC(Two Phase Commitment Protocol)兩階段提交協議(WCF的事務的實現基于此協議)?
????????????????<br />?
????????????????實現分布式事務的關鍵就是兩階段提交協議。在此協議中,一個或多個資源管理器的活動均由一個稱為事務協調器的單獨軟件組件來控制。此協議中的五個步驟如下:?
????????????????<br />?
????????????????1、應用程序調用事務協調器中的提交方法。?
????????????????<br />?
????????????????2、事務協調器將聯絡事務中涉及的每個資源管理器,并通知它們準備提交事務(這是第一階段的開始)。?
????????????????<br />?
????????????????3、為 了以肯定的方式響應準備階段,資源管理器必須將自己置于以下狀態:確保能在被要求提交事務時提交事務,或在被要求回滾事務時回滾事務。大多數資源管理器會將包含其計劃更改的日記文件(或等效文件)寫入持久存儲區中。如果資源管理器無法準備事務,它會以一個否定響應來回應事務協調器。?
????????????????<br />?
????????????????4、事務協調器收集來自資源管理器的所有響應。?
????????????????<br />?
????????????????5、在 第二階段,事務協調器將事務的結果通知給每個資源管理器。如果任一資源管理器做出否定響應,則事務協調器會將一個回滾命令發送給事務中涉及的所有資源管理 器。如果資源管理器都做出肯定響應,則事務協調器會指示所有的資源管理器提交事務。一旦通知資源管理器提交,此后的事務就不能失敗了。通過以肯定的方式響應第一階段,每個資源管理器均已確保,如果以后通知它提交事務,則事務不會失敗。?
????????</p>?
</asp:Content>
????????Inherits="Transaction_Sample" Title="事務(Transaction)" %>?
<asp:Content ID="Content1" ContentPlaceHolderID="head" runat="Server">?
</asp:Content>?
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" runat="Server">?
????????<p>?
????????????????<asp:Label ID="lblErr" runat="server" ForeColor="Red" />?
????????</p>?
????????<p>?
????????????????<asp:Button ID="btnSubmit" runat="server" Text="事務測試" OnClick="btnSubmit_Click" />?
????????????????<br />?
????????????????<br />?
????????????????<asp:GridView ID="GridView1" runat="server">?
????????????????</asp:GridView>?
????????</p>?
????????<p>?
????????????????2PC(Two Phase Commitment Protocol)兩階段提交協議(WCF的事務的實現基于此協議)?
????????????????<br />?
????????????????實現分布式事務的關鍵就是兩階段提交協議。在此協議中,一個或多個資源管理器的活動均由一個稱為事務協調器的單獨軟件組件來控制。此協議中的五個步驟如下:?
????????????????<br />?
????????????????1、應用程序調用事務協調器中的提交方法。?
????????????????<br />?
????????????????2、事務協調器將聯絡事務中涉及的每個資源管理器,并通知它們準備提交事務(這是第一階段的開始)。?
????????????????<br />?
????????????????3、為 了以肯定的方式響應準備階段,資源管理器必須將自己置于以下狀態:確保能在被要求提交事務時提交事務,或在被要求回滾事務時回滾事務。大多數資源管理器會將包含其計劃更改的日記文件(或等效文件)寫入持久存儲區中。如果資源管理器無法準備事務,它會以一個否定響應來回應事務協調器。?
????????????????<br />?
????????????????4、事務協調器收集來自資源管理器的所有響應。?
????????????????<br />?
????????????????5、在 第二階段,事務協調器將事務的結果通知給每個資源管理器。如果任一資源管理器做出否定響應,則事務協調器會將一個回滾命令發送給事務中涉及的所有資源管理 器。如果資源管理器都做出肯定響應,則事務協調器會指示所有的資源管理器提交事務。一旦通知資源管理器提交,此后的事務就不能失敗了。通過以肯定的方式響應第一階段,每個資源管理器均已確保,如果以后通知它提交事務,則事務不會失敗。?
????????</p>?
</asp:Content>
Sample.aspx.cs



























































Web.config
<?xml version="1.0"?>?
<configuration>?
????????<system.serviceModel>?
????????????????<client>?
????????????????????????<!--address - 服務地址-->?
????????????????????????<!--binding - 通信方式-->?
????????????????????????<!--contract - 服務契約-->?
????????????????????????<endpoint address="http://localhost:3502/ServiceHost/Transaction/Hello.svc" binding="wsHttpBinding" contract="TransactionSvc.Hello.IHello" bindingConfiguration="TransactionBindingConfiguration" />?
????????????????????????<endpoint address="http://localhost:3502/ServiceHost/Transaction/Hi.svc" binding="wsHttpBinding" contract="TransactionSvc.Hi.IHi" bindingConfiguration="TransactionBindingConfiguration" />?
????????????????????????<endpoint address="http://localhost:3502/ServiceHost/Transaction/Result.svc" binding="basicHttpBinding" contract="TransactionSvc.Result.IResult" />?
????????????????</client>?
????????????????<bindings>?
????????????????????????<wsHttpBinding>?
????????????????????????????????<!--transactionFlow - 指定該綁定是否應支持流事務-->?
????????????????????????????????<binding name="TransactionBindingConfiguration" transactionFlow="true" />?
????????????????????????</wsHttpBinding>?
????????????????</bindings>?
????????</system.serviceModel>?
</configuration>
<configuration>?
????????<system.serviceModel>?
????????????????<client>?
????????????????????????<!--address - 服務地址-->?
????????????????????????<!--binding - 通信方式-->?
????????????????????????<!--contract - 服務契約-->?
????????????????????????<endpoint address="http://localhost:3502/ServiceHost/Transaction/Hello.svc" binding="wsHttpBinding" contract="TransactionSvc.Hello.IHello" bindingConfiguration="TransactionBindingConfiguration" />?
????????????????????????<endpoint address="http://localhost:3502/ServiceHost/Transaction/Hi.svc" binding="wsHttpBinding" contract="TransactionSvc.Hi.IHi" bindingConfiguration="TransactionBindingConfiguration" />?
????????????????????????<endpoint address="http://localhost:3502/ServiceHost/Transaction/Result.svc" binding="basicHttpBinding" contract="TransactionSvc.Result.IResult" />?
????????????????</client>?
????????????????<bindings>?
????????????????????????<wsHttpBinding>?
????????????????????????????????<!--transactionFlow - 指定該綁定是否應支持流事務-->?
????????????????????????????????<binding name="TransactionBindingConfiguration" transactionFlow="true" />?
????????????????????????</wsHttpBinding>?
????????????????</bindings>?
????????</system.serviceModel>?
</configuration>
運行結果:
單擊"btnSubmit"按鈕后,可以發現,兩個數據庫插入操作,要么都執行,要么都不執行
OK
[源碼下載]
單擊"btnSubmit"按鈕后,可以發現,兩個數據庫插入操作,要么都執行,要么都不執行
OK
[源碼下載]
?
本文轉自webabcd 51CTO博客,原文鏈接:http://blog.51cto.com/webabcd/344160,如需轉載請自行聯系原作者