您的位置:首页 > 其它

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

2017-03-22 16:59 483 查看
今天是速成的第三天,再分享一下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
4000
///<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="
c0c7
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>


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

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

 



 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: