發(fā)文章
發(fā)文工具
撰寫
網(wǎng)文摘手
文檔
視頻
思維導(dǎo)圖
隨筆
相冊(cè)
原創(chuàng)同步助手
其他工具
圖片轉(zhuǎn)文字
文件清理
AI助手
留言交流
今天是速成的第三天,再分享一下WCF中比較常用的一種技術(shù),也就是”事務(wù)“。
在B2B的項(xiàng)目中,一般用戶注冊(cè)后,就有一個(gè)屬于自己的店鋪,此時(shí),我們就要插入兩張表, User和Shop表。
當(dāng)然,要么插入成功,要么全失敗。
第一步: 首先看一下項(xiàng)目的結(jié)構(gòu)圖:
第二步: 準(zhǔn)備工作,我們新建Commerce數(shù)據(jù)庫(kù),用EF去映射,然后新建ServiceWCF類庫(kù),具體步驟就省略,
這一塊不懂可以留言。
第三步:新建一個(gè)Model類庫(kù)。建立兩個(gè)實(shí)體類Shop和User,當(dāng)然自定義類型在WCF中傳輸,
必須在類上加上【DataContract】,屬性上加【DataMember】。
Shop.cs
1 namespace Model 2 { 3 [DataContract] 4 public class Shop 5 { 6 [DataMember] 7 public int ShopID { get; set; } 8 9 [DataMember] 10 public int UserID { get; set; } 11 12 [DataMember] 13 public string ShopName { get; set; } 14 15 [DataMember] 16 public string ShopUrl { get; set; } 17 18 } 19 }
User.cs
1 namespace Model 2 { 3 [DataContract] 4 public class User 5 { 6 [DataMember] 7 public int UserID { get; set; } 8 9 [DataMember] 10 public string UserName { get; set; } 11 12 [DataMember] 13 public string Password { get; set; } 14 } 15 }
第四步:然后在ServiceWCF類庫(kù)中新建兩個(gè)文件Seller.cs 和 ISeller.cs.
ISeller.cs:
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Runtime.Serialization; 5 using System.ServiceModel; 6 using System.Text; 7 8 namespace ServiceWCF 9 { 10 [ServiceContract] 11 public interface ISeller 12 { 13 [OperationContract(Name = "AddUser")] 14 bool Add(Model.User user, out int userID); 15 16 [OperationContract(Name = "AddShop")] 17 bool Add(Model.Shop shop, out int shopID); 18 19 [OperationContract] 20 bool Add(Model.User user, Model.Shop shop); 21 } 22 }
Seller.cs
1 namespace ServiceWCF 2 { 3 public class Seller : ISeller 4 { 5 ///<summary> 6 /// User的插入操作 7 ///</summary> 8 ///<param name="user"></param> 9 ///<param name="userID"></param> 10 ///<returns></returns> 11 public bool Add(Model.User user, out int userID) 12 { 13 using (CommerceEntities db = new CommerceEntities()) 14 { 15 try 16 { 17 User userModel = new User() 18 { 19 UserName = user.UserName, 20 Passwrod = user.Password 21 }; 22 23 db.User.AddObject(userModel); 24 25 db.SaveChanges(); 26 27 userID = userModel.UserID; 28 29 return true; 30 } 31 catch (Exception) 32 { 33 userID = 0; 34 throw; 35 } 36 } 37 } 38 39 ///<summary> 40 /// Shop的插入操作 41 ///</summary> 42 ///<param name="shop"></param> 43 ///<param name="shopID"></param> 44 ///<returns></returns> 45 public bool Add(Model.Shop shop, out int shopID) 46 { 47 using (CommerceEntities db = new CommerceEntities()) 48 { 49 try 50 { 51 52 Shop shopModel = new Shop() 53 { 54 ShopName = shop.ShopName, 55 ShopUrl = shop.ShopUrl, 56 UserID = shop.UserID 57 }; 58 59 db.Shop.AddObject(shopModel); 60 61 db.SaveChanges(); 62 63 shopID = shopModel.ShopID; 64 65 return true; 66 } 67 catch (Exception) 68 { 69 shopID = 0; 70 throw; 71 } 72 } 73 } 74 75 ///<summary> 76 /// User,Shop的插入的操作 77 ///</summary> 78 ///<param name="user"></param> 79 ///<param name="shop"></param> 80 ///<returns></returns>
81 [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 82 public bool Add(Model.User user, Model.Shop shop) 83 { 84 int shopID; 85 int UserID; 86 87 //注意,這個(gè)方法操作了兩個(gè)數(shù)據(jù)庫(kù)實(shí)例,為AddUser和AddShop。所以晉升為分布式事務(wù) 88 if (Add(user, out UserID)) 89 { 90 shop.UserID = UserID; 91 92 return Add(shop, out shopID); 93 } 94 95 return false; 96 } 97 } 98 }
TransactionScopeRequired: 告訴ServiceHost自托管服務(wù),進(jìn)入我的方法,必須給我加上事務(wù)。
TransactionAutoComplete: 方法執(zhí)行中,如果沒(méi)有拋出異常,則自動(dòng)提交。
第五步: 新建Host來(lái)承載了,配置AppConfig,這些細(xì)節(jié)就不再說(shuō)了。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ServiceHost 7 { 8 class Program 9 { 10 static void Main(string[] args) 11 { 12 System.ServiceModel.ServiceHost host = new System.ServiceModel.ServiceHost(typeof(ServiceWCF.Seller)); 13 14 host.Open(); 15 16 Console.WriteLine("WCF 服務(wù)已經(jīng)開(kāi)啟!"); 17 18 Console.Read(); 19 } 20 } 21 }
1 <?xml version="1.0" encoding="utf-8"?> 2 <configuration> 3 <system.web> 4 <compilation debug="true" /> 5 </system.web> 6 <!-- 部署服務(wù)庫(kù)項(xiàng)目時(shí),必須將配置文件的內(nèi)容添加到 7 主機(jī)的 app.config 文件中。System.Configuration 不支持庫(kù)的配置文件。--> 8 <system.serviceModel> 9 <services> 10 <service name="ServiceWCF.Seller"> 11 <endpoint address="" binding="wsHttpBinding" contract="ServiceWCF.ISeller"> 12 <identity> 13 <dns value="localhost" /> 14 </identity> 15 </endpoint> 16 <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" /> 17 <host> 18 <baseAddresses> 19 <add baseAddress="http://localhost:8732/Seller/" /> 20 </baseAddresses> 21 </host> 22 </service> 23 </services> 24 <behaviors> 25 <serviceBehaviors> 26 <behavior> 27 <!-- 為避免泄漏元數(shù)據(jù)信息, 28 請(qǐng)?jiān)诓渴鹎皩⒁韵轮翟O(shè)置為 false 并刪除上面的元數(shù)據(jù)終結(jié)點(diǎn) --> 29 <serviceMetadata httpGetEnabled="True" /> 30 <!-- 要接收故障異常詳細(xì)信息以進(jìn)行調(diào)試, 31 請(qǐng)將以下值設(shè)置為 true。在部署前設(shè)置為 false 32 以避免泄漏異常信息--> 33 <serviceDebug includeExceptionDetailInFaults="False" /> 34 </behavior> 35 </serviceBehaviors> 36 </behaviors> 37 </system.serviceModel> 38 <connectionStrings> 39 <add name="CommerceEntities" connectionString="metadata=res://*/Commerce.csdl|res://*/Commerce.ssdl|res://*/Commerce.msl;provider=System.Data.SqlClient;provider connection string="Data Source=VONXCEVF0IT7JDJ;Initial Catalog=Commerce;Integrated Security=True;MultipleActiveResultSets=True"" providerName="System.Data.EntityClient" /> 40 </connectionStrings> 41 </configuration>
第六步:開(kāi)啟WCF服務(wù),新建ServiceClient類庫(kù),然后用信道生成實(shí)例。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.ServiceModel; 6 using ServiceWCF; 7 8 namespace ServiceClient 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 var user = new Model.User() 15 { 16 UserName = "huangxincheng520", 17 Password = "i can fly" 18 }; 19 20 var shop = new Model.Shop() 21 { 22 ShopName = "shopex", 23 ShopUrl = "http://www." 24 }; 25 26 var factory = new ChannelFactory<ISeller>(new WSHttpBinding(),
new EndpointAddress("http://localhost:8732/Seller/")); 27 28 var client = factory.CreateChannel(); 29 30 if (client.Add(user, shop)) 31 Console.WriteLine("huangxincheng520, 恭喜你,數(shù)據(jù)插入成功。"); 32 else 33 Console.WriteLine("huangxincheng520, 嗚嗚,數(shù)據(jù)插入失敗。"); 34 35 Console.Read(); 36 } 37 } 38 }
最后就是測(cè)試了:
首先:走正常流程。client.Add方法調(diào)用服務(wù)器端,運(yùn)行效果如圖所示:
是的,數(shù)據(jù)已經(jīng)正常插入成功,對(duì)Client端而言,這個(gè)操作是透明的。
然后: 我們?cè)赟eller類中的Add方法中故意加入異常??葱Ч印?/a>
1 ///<summary> 2 /// User,Shop的插入的操作 3 ///</summary> 4 ///<param name="user"></param> 5 ///<param name="shop"></param> 6 ///<returns></returns> 7 [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)] 8 public bool Add(Model.User user, Model.Shop shop) 9 { 10 int shopID; 11 int UserID; 12 13 if (Add(user, out UserID)) 14 { 15 //注意注意,我在Adduser成功的情況下,拋出異常,看是否回滾。 16 throw new Exception(); 17 18 shop.UserID = UserID; 19 20 return Add(shop, out shopID); 21 } 22 23 return false; 24 }
截圖如下:
哈哈,拋出異常了,我的Exception起到效果了,再來(lái)看一下數(shù)據(jù)庫(kù)。大家都知道會(huì)發(fā)生什么了,對(duì)的,異常不再產(chǎn)生數(shù)據(jù)了,
還是先前產(chǎn)生了那條數(shù)據(jù),說(shuō)明起到效果了。
來(lái)自: 昵稱10504424 > 《Wcf》
0條評(píng)論
發(fā)表
請(qǐng)遵守用戶 評(píng)論公約
WCF服務(wù)如何獲得客戶端IP地址信息(轉(zhuǎn))
今天新開(kāi)了一個(gè)系列文章《WCF熱門問(wèn)題編程示例》:主要是針對(duì)WCF里比較有價(jià)值的問(wèn)題的收集和整理,進(jìn)行分析和 編程實(shí)踐。WCF服務(wù)能否獲取客戶端地址IP信息,這個(gè)問(wèn)題相信很多人都遇到過(guò)。WSHttpBinding_...
WCF之旅(8):WCF中的Session和Instancing Management
WCF中的Session.如果通過(guò)以下的方式定義ServiceContract使之不支持Session,或者使用不支持Session的Binding(順便說(shuō)一下,Session的支...
我的WCF之旅(1):創(chuàng)建一個(gè)簡(jiǎn)單的WCF程序
為了使讀者對(duì)基于WCF的編程模型有一個(gè)直觀的映像,我將帶領(lǐng)讀者一步一步地創(chuàng)建一個(gè)完整的WCF應(yīng)用?;贗IS的服務(wù)寄宿要求相應(yīng)的WCF服務(wù)...
[WCF 學(xué)習(xí)筆記](méi) 3. 消息交換
AddServiceEndpoint(typeof(IContract), new BasicHttpBinding(), "http://localhost:8080/myservice");ChannelFactory<IContract> factory = new ChannelFactory<IContrac...
ASP.Net MVC開(kāi)發(fā)基礎(chǔ)學(xué)習(xí)筆記:五、區(qū)域、模板頁(yè)與WebAPI初步
ASP.Net MVC開(kāi)發(fā)基礎(chǔ)學(xué)習(xí)筆記:五、區(qū)域、模板頁(yè)與WebAPI初步一、區(qū)域—麻雀雖小,五臟俱全的迷你MVC項(xiàng)目1.1 Area的興起。有了我們上面...
WCF之Channel(二)
WCF之Channel(二)最后提到ICommunicationObject,所有的Channel、ChannelListener和ChannelFactory都實(shí)現(xiàn)了這個(gè)接口,例如:此外,WCF...
[老老實(shí)實(shí)學(xué)WCF] 第二篇 配置WCF
[老老實(shí)實(shí)學(xué)WCF] 第二篇 配置WCF.老老實(shí)實(shí)學(xué)WCF.建立基地址:這里用了相對(duì)地址''HelloWCFService'',他會(huì)和基地址組合在一起(排在后面)成為終結(jié)點(diǎn)的地址,這里也可以指定為空字符串...
跟我一起學(xué)WCF(8)
這樣的運(yùn)行結(jié)果好像與我們之前所說(shuō)的WCF默認(rèn)Session支持矛盾,因?yàn)槿绻鸚CF默認(rèn)的方式PerSession的話,則服務(wù)實(shí)例是和Proxy綁定在一起,...
Using WCF Callback Services Throttling
Required, CallbackContract=typeof(IEventSystemCallback))] interface IEventSystem { [OperationContract(IsOneWay=true)] void Subscribe();The IEventSystemCallback interface is the callback c...
微信掃碼,在手機(jī)上查看選中內(nèi)容