国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

基于Windows通訊基礎的事務性服務創建

2019-11-17 04:41:00
字體:
來源:轉載
供稿:網友
閱讀提示 今天,事務不再僅適用于數據庫應用程序。通過使用Windows Communication Foundation(Windows通訊基礎,簡寫為WCF)中的統一事務系統,你不僅可以為數據庫應用程序創建事務性服務,也可以為發送消息、工作流以及其它類型的應用程序創建事務性服務。

   WCF的核心目的是幫助你構建基于.NET的安全可靠的和事務性的服務。在本文中,你將會在前兩篇代碼基礎上進行構建以創建你的第一個事務性服務。

  一、WCF中的事務

  事務能夠確保一組相關的操作以一個原子單元的方式發生。換句話說,在該單元中的每個操作必須都成功或都失敗。WCF提供了一個集中的事務系統-你可以用來治理你的事務操作。在過去,事務邏輯通常用作一個標準方法來治理數據庫事務(還記得VB中的BeginTrans和CommitTrans嗎?),但是不存在標準方法來執行非數據庫事務。WCF的目標就是用一個統一事務系統來解決這個問題-你可以應用于數據庫、通訊或其它的事務性行為中。

  WCF編程模型使得事務易于使用。為此,你要把一組操作組織成一個事務范圍。這個范圍定義了一個事務的原子。下列偽代碼說明了這一點:

Using(TransactionScope theScope = new
TransactionScope())
{
Service1.submitRequest(myRequest);
Service2.submitRequest(myOtherRequest);
Service3.submitRequest(myFinalRequest);
theScope.Complete();
}
  二、構建你的第一個可事務化的服務

  一開始,你首先需要一個事務性的服務。這就意味著你愿意讓你的服務參予一個在你的契約操作上的由客戶初始化的事務,由你來指定(使用屬性和配置文件)該事務的行為。在構建該服務后,你將逐步分析構建一個客戶-在調用該服務時它使用一事務范圍。假如你已經安裝了Visual Studio.NET,那么你應該很快就能夠運行起來。

  讓我們首先用Visual Studio.NET創建一新的Web站點。然后,選擇IndigoService工程類型并且把它命名為Tservice。你的屏幕應該看上去如圖1所示。

基于Windows通訊基礎的事務性服務創建(圖一)
圖1.創建一新的Indigo服務:在選擇Indigo服務工程類型并命名其為Tservice后,你的屏幕看上去的樣子。

  Visual Studio將用一個稱為IMyService的接口為你創建一個缺省的服務和一個稱為MyService的服務類。你將在App_Code子文件夾下的Service.cs文件中找到該服務類的代碼。你可以用顯示在列表1中的代碼來代替在這個文件中的代碼。你還將需要添加一個到System.Transactions命名空間的參考引用-以便在你編譯它時,代碼能夠正確工作。

  列表1.可事務化的Web服務:

//這個Web服務與在前一篇文章中所描述的TemperatureService相同,
//但是這個版本包含了使該服務成為事務性的屬性.
using System;
using System.ServiceModel;
using System.Transactions;
[ServiceContract(Namespace = "http://Devx.Indigo.Transactions")]
public interface ITransactableTemperatures
{
[OperationContract]
[TransactionFlow(TransactionFlowOption.Required)]
double ftoc(double f);
[OperationContract]
[TransactionFlow(TransactionFlowOption.Required)]
double ctof(double c);
}
[ServiceBehavior(TransactionIsolationLevel =
IsolationLevel.ReadCommitted)]
public class TransactableTemperatures : ITransactableTemperatures
{
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double ftoc(double f)
{
double dReturn = 0.0;
dReturn = ((f - 32) * 5) / 9;
return dReturn;
}
[OperationBehavior(TransactionScopeRequired = true,
TransactionAutoComplete = true)]
public double ctof(double c)
{
double dReturn = 0.0;
dReturn = ((c + 32) * 9) / 5;
return dReturn;
}
}
  注重,該事務性Web服務的代碼等同于以前文章中的"溫度"Web服務-用一些新的屬性把它描述為事務性的。

  當在接口級上定義方法時,OperationContract的屬性被用[TransactionFlow]屬性加以修飾。這可以通知運行時刻在OperationContract上的操作存在疑問時如何在一個事務條件下作出響應。其有效值為Allowed-當操作可以或不可以用于一個事務中時;而當永不會用于一個事務中時它取值為NotAllowed;當必須在一個事務范圍內使用時,它取值為Required。

  在服務級上,[ServiceBehavior]屬性通過使用TransactionIsolationLevel屬性來指定事務的屬性。理想情況下,事務應該展示四個要害屬性-atomic,consistent,isolated和durable,縮略詞為ACID。然而,保持它們之間彼此完全相互隔離可以使得持有資源鎖的時間比必需的時間更長些-這可能導致鎖競爭、降低性能甚至導致死鎖條件-此時,不同的事務彼此都需要鎖來完成自身而該鎖卻由另外的事務持有。設置隔離級別讓你選擇最匹配于其它應用程序的隔離程度。你可以通過把IsolationLevel屬性值設置為ServiceBehavior的TransactionIsolationLevel屬性值來設置隔離級別。在列表1中,IsolationLevel被設置為ReadCommited-這意味著在該事務中不能讀取volatile型數據,但是能被修改。要全面地了解不同的隔離級別屬性值,你可以參考幫助文檔中的System..Transactions.IsolationLevel枚舉。注重,還有一個枚舉System.Data.IsolationLevel;因此,假如你在代碼中參考System.Data命名空間,那么你必須以完全限定方式來使用這個IsolationLevel以避免沖突問題。

  最后,列表1使用[OperationBehavior]屬性定義了在服務中的Web方法中的事務行為-它把自己的TransactionScope屬性設置為true。這個TransactionScope設置指明必須在某一范圍內調用該操作(這將在客戶內部展示出來)。TransactionAutoComplete屬性也被設置為true來指示當方法完成執行時,將把該事務標志為complete。假如TransactionAutoComplete屬性被設置為false,那么你將調用OperationContext.Current.SetTransactionComplete()方法來手工設置該事務的正確完成;否則,該事務將標志其為失敗的。

三、運用服務

  為了運行這個服務,你還需要做一些細節工作。首先,你必須更改Service.svc文件以指向新的類和接口。在該文件中,找到下面一行:

<span class="pf">Class="MyService"
  把它改變為:

<span class="pf">Class="TransactableTemperatures</span>"
  下一步,配置運行時刻以答應事務;否則,運行該服務將引起一個錯誤。為此,從一個命令行提示符上發出如下命令:

  Xws_reg --wsat+

  該命令配置MSDTC以處理WS-Atomic事務(WSAT)。

  當然在最后,你需要編輯web.config文件以為你的服務配置serviceModel設置。完整的web.config文件看上去如下樣子:

<?xml version="1.0"?>
<configuration xmlns=
"http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.serviceModel>
<services>
<service type="TransactableTemperatures">
<endpoint contract="ITransactableTemperatures" binding="wsHttpBinding" bindingConfiguration="Binding1"/>
</service >
</services >
<bindings>
  圖2.運行服務:該圖顯示出從一個瀏覽器中運行示例事務性服務的結果。

<wsHttpBinding>
<binding configurationName="Binding1"
transactionFlow="true" />
</wsHttpBinding>
</bindings>
</system.serviceModel>
<system.web>
<compilation debug="true">
<assemblies>
<add assembly="System.Transactions,
Version=2.0.0.0,
Culture=neutral,
PublicKeyToken=B77A5C561934E089"/>
</assemblies>
</compilation>
</system.web>
</configuration>
  修改完web.config后,運行該服務將產生如圖2所示的屏幕快照。

基于Windows通訊基礎的事務性服務創建(圖二)
圖2.運行服務-該圖顯示出示例事務性服務從一個瀏覽器中運行的結果。

  四、為該服務構建一客戶端

  當服務可用時,你可以把一個Windows表單客戶應用程序添加到工程上。表單布局如圖3所示;當然你也可以只使用下載版本。

基于Windows通訊基礎的事務性服務創建(圖三)
圖3.設計客戶-該圖顯示出Visual Studio表單設計器中的Windows表單客戶應用程序。

  用戶把一個值輸入到該文本框中,并使用單選按鈕選擇一個轉換方法,然后點擊Convert按鈕來調用該服務。但是在創建相應的代碼之前,你需要創建到該服務的一個代理。為此,使用下面在服務頁面上的指令(見圖2)-使用svcutil.exe工具來生成一個代理文件和一個客戶配置文件。從我的試驗看出,不使用生成的配置文件(名叫output.config)更為輕易些;而是,只創建你自己的版本-它僅使用當前應用程序要求的部分,并命名它為App.config。

  為運行svcutil.exe,可以從一個命令行提示符上運行下列命令:

  Scvutil <url of service>?wsdl

  前面的命令創建了兩個文件-它們可能的命名為tempuri.org.cs和output.config。其中tempura.org.cs文件包含你需要用于調用你的服務的代理,因此現在把它添加到你的Windows客戶工程。

  接下來,把一個命為App.config的新文件添加到該工程并為其創建如下內容:(為簡化起見,這些是output.config中的過濾結果)

<?xml version="1.0" encoding="utf-8" ?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<system.serviceModel>
<client>
<endpoint configurationName="default" address= "http://atlas/TransactableService/Service.svc/"
binding="wsHttpBinding" bindingConfiguration="Binding1" contract="ITransactableTemperatures"/>
</client>
<bindings>
<wsHttpBinding>
<binding configurationName="Binding1" transactionFlow="true" />
</wsHttpBinding>
</bindings>
</system.serviceModel>
</configuration>
  現在,你可以設置BTn_Click事件處理器來調用該事務性服務-使用如下的一個事務性范圍:


PRivate void btnConvert_Click(object sender, EventArgs e){
using(TransactableTemperaturesProxy theProxy =
new TransactableTemperaturesProxy("default"))
{
 TransactionOptions transactionOptions = new TransactionOptions();
 transactionOptions.IsolationLevel =IsolationLevel.ReadCommitted;
 using (
  TransactionScope tx = new TransactionScope(
   TransactionScopeOption.RequiresNew,transactionOptions))
  {
   double d = Convert.ToDouble(txtIn.Text);
   double dResult = 0.0D;
   if (rbCToF.Checked)
    dResult = theProxy.ctof(d);
   else
    dResult = theProxy.ftoc(d);
    lblOut.Text = dResult.ToString();
    tx.Complete();
  }
 }
}
  前面的代碼首先使用缺省的配置文件名建立代理。你可以看到這是在App.config內的配置文件名。

  接下來,該代碼創建一個新的為IsolationLevel.ReadCommitted(匹配服務IsolationLevel設置,如前面所討論的)而配置的transactionOptions集合。

  最后,該代碼在{}塊中創建一個新的名叫tx的TransactionScope,這樣以來發生在該塊中的每一件事情都在這個tx范圍內被事務化。該塊中的最后一行代碼把tx標志設置為Complete,并且該事務成功結束。

  事務在任何相連接的系統中都是極其重要的。直到現在,開發者往往把事務與數據庫方法相提并論,但是如今事務也能夠良好地應用于其它類型的操作。在任何相連接的系統中,在一個工作流中傳遞的消息能夠大大地受益于事務性。當把一些健壯的,企業級的基礎結構放置到一起時,在你的代碼中提供可事務性的服務至關重要。所以,事務性是WCF中最重要的支柱之一。

  在本文中,你看到了怎樣構建一個簡單的事務性服務以及怎樣從一個Windows表單客戶程序中消費它。盡管這個例子只涉及到可能性的一點皮毛,但是它應該能夠讓你理解如何為你的客戶構建和提供事務性軟件服務!

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 奉节县| 甘南县| 松江区| 高安市| 博野县| 左权县| 微博| 加查县| 商丘市| 阿图什市| 如东县| 田林县| 怀仁县| 彭山县| 临武县| 南雄市| 海丰县| 苗栗县| 水富县| 新安县| 湘潭县| 泸定县| 衡东县| 宁陵县| 施秉县| 正蓝旗| 永安市| 澜沧| 嘉善县| 庐江县| 诸城市| 南木林县| 高阳县| 晋宁县| 将乐县| 岳普湖县| 宣威市| 利津县| 保亭| 三门峡市| 屏东市|