wcf系列学习5天速成——第三天 分布性事务的使用 有时间再验证下 不同库的操作

原文地址:http://www.cnblogs.com/huangxincheng/archive/2011/11/06/2238273.html

今天是速成的第三天,再分享一下WCF中比较常用的一种技术,也就是”事务“。

在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表。

当然,要么插入成功,要么全失败。

第一步: 首先看一下项目的结构图:

第二步: 准备工作,我们新建Commerce数据库,用EF去映射,然后新建ServiceWCF类库,具体步骤就省略,

这一块不懂可以留言。

第三步:新建一个Model类库。建立两个实体类Shop和User,当然自定义类型在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类库中新建两个文件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 ISeller12     {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                 try16                 {17                     User userModel = new User()18                     {19                         UserName = user.UserName,20                         Passwrod = user.Password21                     };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                 try50                 {51 52                     Shop shopModel = new Shop()53                           {54                               ShopName = shop.ShopName,55                               ShopUrl = shop.ShopUrl,56                               UserID = shop.UserID57                           };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             //注意,这个方法操作了两个数据库实例,为AddUser和AddShop。所以晋升为分布式事务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自托管服务,进入我的方法,必须给我加上事务。

TransactionAutoComplete:   方法执行中,如果没有抛出异常,则自动提交。

第五步: 新建Host来承载了,配置AppConfig,这些细节就不再说了。

 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 服务已经开启!");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   <!-- 部署服务库项目时,必须将配置文件的内容添加到  7   主机的 app.config 文件中。System.Configuration 不支持库的配置文件。--> 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           <!-- 为避免泄漏元数据信息,28           请在部署前将以下值设置为 false 并删除上面的元数据终结点  -->29           <serviceMetadata httpGetEnabled="True" />30           <!-- 要接收故障异常详细信息以进行调试,31           请将以下值设置为 true。在部署前设置为 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=&quot;Data Source=VONXCEVF0IT7JDJ;Initial Catalog=Commerce;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" />40   </connectionStrings>41 </configuration>

第六步:开启WCF服务,新建ServiceClient类库,然后用信道生成实例。

 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 Program11     {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.shopex.cn"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, 恭喜你,数据插入成功。");32             else33                 Console.WriteLine("huangxincheng520, 呜呜,数据插入失败。");34 35             Console.Read();36         }37     }38 }

最后就是测试了:

首先:走正常流程。client.Add方法调用服务器端,运行效果如图所示:

是的,数据已经正常插入成功,对Client端而言,这个操作是透明的。

然后:  我们在Seller类中的Add方法中故意加入异常。看效果咋样。

 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起到效果了,再来看一下数据库。大家都知道会发生什么了,对的,异常不再产生数据了,

还是先前产生了那条数据,说明起到效果了。

时间: 2024-10-13 20:51:06

wcf系列学习5天速成——第三天 分布性事务的使用 有时间再验证下 不同库的操作的相关文章

wcf系列学习5天速成——第三天 事务的使用

原文:wcf系列学习5天速成--第三天 事务的使用 今天是速成的第三天,再分享一下WCF中比较常用的一种技术,也就是”事务“. 在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表. 当然,要么插入成功,要么全失败. 第一步: 首先看一下项目的结构图: 第二步: 准备工作,我们新建Commerce数据库,用EF去映射,然后新建ServiceWCF类库,具体步骤就省略, 这一块不懂可以留言. 第三步:新建一个Model类库.建立两个实体类Sho

wcf系列学习5天速成——第五天 服务托管

原文:wcf系列学习5天速成--第五天 服务托管 今天是系列的终结篇,当然要分享一下wcf的托管方面的知识. wcf中托管服务一般有一下四种: Console寄宿:             利于开发调试,但不是生产环境中的最佳实践. winform寄宿:             方便与用户进行交互,用户想开就开,想关就关,但如果机器重启了,不得不自己手动开一下,危险+麻烦. IIS寄宿:                    此寄宿在实战项目中得到了广泛的应用. 好处有:随系统启动和停止. ii

wcf系列学习5天速成——第四天 wcf之分布式架构

原文:wcf系列学习5天速成--第四天 wcf之分布式架构 今天是wcf系列的第四天,也该出手压轴戏了.嗯,现在的大型架构,都是神马的, nginx鸡群,iis鸡群,wcf鸡群,DB鸡群,由一个人作战变成了群殴....... 今天我就分享下wcf鸡群,高性能架构中一种常用的手法就是在内存中维护一个叫做“索引”的内存数据库, 在实战中利用“索引”这个概念做出"海量数据“的秒杀. 好,先上图: 这个图明白人都能看得懂吧.因为我的系列偏重于wcf,所以我重点说下”心跳检测“的实战手法. 第一步:上一下

wcf系列5天速成——第一天 binding的使用(1)

原文:wcf系列5天速成--第一天 binding的使用(1) 作为WCF速成系列,只介绍些项目开发中常用到的实战知识. 学习wcf,还是对其中的几个术语要了解一下.wcf中有一个ABC的概念,就是 第一: "A" 是地址,就是告诉别人我wcf在何处. 第二: "B"是绑定,就是告诉别人应该走什么路才能过来. 第三: "C"是契约:就是告诉别人我wcf这里有哪些东西. 项目开发中常用到的三种绑定: 第一:wsHttpBinding,   这个bi

wcf系列5天速成——第二天 binding的使用(2)

原文:wcf系列5天速成--第二天 binding的使用(2) 承接上一章,今天来讲MSMQ在实战项目中的应用.众所周知,放了防止订单丢失,我们都是采用Order过一下MSMQ. MSMQ的优点个人认为是:先天的异步消息发送和天生的自动负载均衡. 好了,看看MSMQ在实战中的应用. 第一步:  准备工作,安装MSMQ服务器,然后勾上下图选项,安装即可. 第二步:新建一个类库.建立两个文件IOrder.cs,Order.cs.截图如下. 第三步:新建Host的Console程序,建立App.con

Android高手速成--第三部分 优秀项目

主要介绍那些Android还不错的完整项目,目前包含的项目主要依据是项目有意思或项目分层规范比较好.Linux项目地址:https://github.com/torvalds/linuxAndroid项目地址:https://android.googlesource.com/ 或 https://github.com/android以上两个项目,不解释 (1) ZXing二维码扫描工具项目地址:https://github.com/zxing/zxing 或 https://code.googl

算法系列15天速成——第三天 七大经典排序【下】

原文:算法系列15天速成--第三天 七大经典排序[下] 今天跟大家聊聊最后三种排序: 直接插入排序,希尔排序和归并排序. 直接插入排序: 这种排序其实蛮好理解的,很现实的例子就是俺们斗地主,当我们抓到一手乱牌时,我们就要按照大小梳理扑克,30秒后, 扑克梳理完毕,4条3,5条s,哇塞......  回忆一下,俺们当时是怎么梳理的. 最左一张牌是3,第二张牌是5,第三张牌又是3,赶紧插到第一张牌后面去,第四张牌又是3,大喜,赶紧插到第二张后面去, 第五张牌又是3,狂喜,哈哈,一门炮就这样产生了.

日均百万PV架构第三弹(分布内容为王)

接续接上篇 缓存时代来临 为蓝本,继续改造我们的百万级站点架构,这次我们 拿之前存储静态内容的 nfs 开刀,众所周知 nfs 的多台集群节点下可能由于多重 原因(磁盘io , 网络带宽, 并发场景),不适合做文件共享系统的基础结构. 互联网站点中,存在大量图片或其他静态内容,并且这些内容一般在1M之内,对于 海量小文件,我们将采用mogilefs分布式文件系统来完成.其中概念自行google. # mogilefs分布式文件系统工作流程 架构已经愈发复杂,我们需要从新梳理一下.从下表中应该很容

linux下oracle11G DG搭建(三):围绕备库搭建操作

环境 名称 主库 备库 主机名 bjsrv shsrv 软件版本 RedHat Enterprise5.5.Oracle 11g 11.2.0.1 RedHat Enterprise5.5.Oracle 11g 11.2.0.1 三.围绕备库操作: 1.备库-修改初始化参数文件 $cd$ORACLE_HOME/dbs $df -h $vi initshdb.ora 修改简要说明: *.audit_file_dest='/u01/app/oracle/admin/sh/adump' //审计文件存