博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
wcf系列学习5天速成——第三天 分布性事务的使用 有时间再验证下 不同库的操作...
阅读量:6076 次
发布时间:2019-06-20

本文共 7410 字,大约阅读时间需要 24 分钟。

原文地址:

今天是速成的第三天,再分享一下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 /// 6 /// User的插入操作 7 /// 8 /// 9 /// 10 ///
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 /// 40 /// Shop的插入操作 41 /// 42 /// 43 /// 44 ///
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 /// 76 /// User,Shop的插入的操作 77 /// 78 /// 79 /// 80 ///
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 
2
3
4
5
6
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
29
30
33
34
35
36
37
38
39
40
41

第六步:开启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
(new WSHttpBinding(),
new EndpointAddress(")); 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   ///  2 /// User,Shop的插入的操作  3 ///  4 ///  5 ///  6 ///
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起到效果了,再来看一下数据库。大家都知道会发生什么了,对的,异常不再产生数据了,

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

 

转载地址:http://lbxgx.baihongyu.com/

你可能感兴趣的文章
elasticsearch 服务安全配置
查看>>
R3.4.0安装包时报错“需要TRUE/FALSE值的地方不可以用缺少值”,需升级到R3.5.0
查看>>
Java学习3_一些基础3_16.5.7
查看>>
通过PowerShell获取域名whois信息
查看>>
Python基础之给函数增加元信息
查看>>
痞子衡嵌入式:开启NXP-MCUBootUtility工具的HAB加密功能 - CST(中英双语)
查看>>
洛谷——2639[USACO09OCT]Bessie的体重问题Bessie's We…——01
查看>>
(转)推荐系统—从入门到精通(论文选摘)
查看>>
HDOJ 1025 DP+二分
查看>>
maven的生命周期和插件
查看>>
研究 Table DOM对象的属性和方法
查看>>
android_orm框架之greenDAO(一)
查看>>
SQL基础语句
查看>>
SQLiteDatabase里面的简单操作数据库的方法
查看>>
闲着没事,写个委托、异步委托玩玩
查看>>
WHM(Web Hosting Manager)/CPANEL 设置及linux 文件权限 经验
查看>>
Problem G
查看>>
前端图片优化方案
查看>>
python迭代、列表生成式
查看>>
matlab-可视化图像阈值选择GUI工具
查看>>