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

转载 2012年03月22日 15:34:00

今天是速成的第三天,再分享一下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 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             //注意,这个方法操作了两个数据库实例,为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 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.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             else
33                 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起到效果了,再来看一下数据库。大家都知道会发生什么了,对的,异常不再产生数据了,

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

 

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

今天是速成的第三天,再分享一下WCF中比较常用的一种技术,也就是”事务“。   在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表。 当然...

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

原文地址:http://www.cnblogs.com/huangxincheng/archive/2011/11/13/2247227.html 今天是系列的终结篇,当然要分享一下wcf的托管...
  • lzkqcc
  • lzkqcc
  • 2017年06月27日 16:56
  • 90

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

今天是系列的终结篇,当然要分享一下wcf的托管方面的知识。   wcf中托管服务一般有一下四种:   Console寄宿:             利于开发调试,但不是生产环境中的最佳实践。 ...

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

今天是wcf系列的第四天,也该出手压轴戏了。嗯,现在的大型架构,都是神马的, nginx鸡群,iis鸡群,wcf鸡群,DB鸡群,由一个人作战变成了群殴.......   今天我就分享下wcf鸡群...

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

wcf系列学习5天速成——第四天 wcf之分布式架构 今天是wcf系列的第四天,也该出手压轴戏了。嗯,现在的大型架构,都是神马的, nginx鸡群,iis鸡群,wcf鸡群,DB鸡群,由一个人作战变成了...

【.Net码农】huangxincheng一线码农系列--wcf系列学习5天速成

wcf系列学习5天速成——第五天 服务托管 摘要: 今天是系列的终结篇,当然要分享一下wcf的托管方面的知识。wcf中托管服务一般有一下四种:Console寄宿: 利于开发调试,但不是生...

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

作为WCF速成系列,只介绍些项目开发中常用到的实战知识。   学习wcf,还是对其中的几个术语要了解一下。wcf中有一个ABC的概念,就是            第一: "A" 是地址,就是告诉...

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

作为WCF速成系列,只介绍些项目开发中常用到的实战知识。   学习wcf,还是对其中的几个术语要了解一下。wcf中有一个ABC的概念,就是            第一: "A" 是地址,就是告诉...

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

原文地址:http://www.cnblogs.com/huangxincheng/archive/2011/10/23/2221845.html 作为WCF速成系列,只介绍些项目开发中常用到的...
  • lzkqcc
  • lzkqcc
  • 2017年06月27日 16:42
  • 163

WCF系列5天速成教程

  • 2013年09月21日 13:34
  • 1.36MB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:wcf系列学习5天速成——第三天 事务的使用
举报原因:
原因补充:

(最多只允许输入30个字)