今天是速成的第三天,再分享一下WCF中比较常用的一种技术,也就是”事务“。
在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表。
当然,要么插入成功,要么全失败。
第一步:首先看一下项目的结构图:
第二步:准备工作,我们新建Commerce数据库,用EF去映射,然后新建ServiceWCF类库,具体步骤就省略
第三步:新建一个Model类库。建立两个实体类Shop和User,当然自定义类型在WCF中传输,必须在类上加上【DataContract】,属性上加【DataMember】。Shop.cs
1namespaceModel
2{
3[DataContract]
4publicclassShop
5{
6[DataMember]
7publicintShopID {get;set; }
8
9[DataMember]
10publicintUserID {get;set; }
11
12[DataMember]
13publicstringShopName {get;set; }
14
15[DataMember]
16publicstringShopUrl {get;set; }
17
18}
19}
User.cs
1namespaceModel
2{
3[DataContract]
4publicclassUser
5{
6[DataMember]
7publicintUserID {get;set; }
8
9[DataMember]
10publicstringUserName {get;set; }
11
12[DataMember]
13publicstringPassword {get;set; }
14}
15}
第四步:然后在ServiceWCF类库中新建两个文件Seller.cs 和 ISeller.cs.
ISeller.cs:
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Linq;
4usingSystem.Runtime.Serialization;
5usingSystem.ServiceModel;
6usingSystem.Text;
7
8namespaceServiceWCF
9{
10[ServiceContract]
11publicinterfaceISeller
12{
13[OperationContract(Name ="AddUser")]
14boolAdd(Model.User user,outintuserID);
15
16[OperationContract(Name ="AddShop")]
17boolAdd(Model.Shop shop,outintshopID);
18
19[OperationContract]
20boolAdd(Model.User user, Model.Shop shop);
21}
22}
Seller.cs
1namespaceServiceWCF
2{
3publicclassSeller : ISeller
4{
5///6///User的插入操作
7///8///
9///
10///11publicboolAdd(Model.User user,outintuserID)
12{
13using(CommerceEntities db =newCommerceEntities())
14{
15try
16{
17User userModel =newUser()
18{
19UserName = user.UserName,
20Passwrod = user.Password
21};
22
23db.User.AddObject(userModel);
24
25db.SaveChanges();
26
27userID = userModel.UserID;
28
29returntrue;
30}
31catch(Exception)
32{
33userID =;
34throw;
35}
36}
37}
38
39///40///Shop的插入操作
41///42///
43///
44///45publicboolAdd(Model.Shop shop,outintshopID)
46{
47using(CommerceEntities db =newCommerceEntities())
48{
49try
50{
51
52Shop shopModel =newShop()
53{
54ShopName = shop.ShopName,
55ShopUrl = shop.ShopUrl,
56UserID = shop.UserID
57};
58
59db.Shop.AddObject(shopModel);
60
61db.SaveChanges();
62
63shopID = shopModel.ShopID;
64
65returntrue;
66}
67catch(Exception)
68{
69shopID =;
70throw;
71}
72}
73}
74
75///76///User,Shop的插入的操作
77///78///
79///
80///
81[OperationBehavior(TransactionScopeRequired=true,TransactionAutoComplete=true)]
82publicboolAdd(Model.User user, Model.Shop shop)
83{
84intshopID;
85intUserID;
86
87//注意,这个方法操作了两个数据库实例,为AddUser和AddShop。所以晋升为分布式事务88if(Add(user,outUserID))
89{
90shop.UserID = UserID;
91
92returnAdd(shop,outshopID);
93}
94
95returnfalse;
96}
97}
98}
TransactionScopeRequired:告诉ServiceHost自托管服务,进入我的方法,必须给我加上事务。
TransactionAutoComplete: 方法执行中,如果没有抛出异常,则自动提交。
第五步:新建Host来承载了,配置AppConfig,这些细节就不再说了。
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Linq;
4usingSystem.Text;
5
6namespaceServiceHost
7{
8classProgram
9{
10staticvoidMain(string[] args)
11{
12System.ServiceModel.ServiceHost host =newSystem.ServiceModel.ServiceHost(typeof(ServiceWCF.Seller));
13
14host.Open();
15
16Console.WriteLine("WCF 服务已经开启!");
17
18Console.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类库,然后用信道生成实例。
1usingSystem;
2usingSystem.Collections.Generic;
3usingSystem.Linq;
4usingSystem.Text;
5usingSystem.ServiceModel;
6usingServiceWCF;
7
8namespaceServiceClient
9{
10classProgram
11{
12staticvoidMain(string[] args)
13{
14varuser =newModel.User()
15{
16UserName ="huangxincheng520",
17Password ="i can fly"
18};
19
20varshop =newModel.Shop()
21{
22ShopName ="shopex",
23ShopUrl ="http://www.shopex.cn"
24};
25
26var factory = new ChannelFactory(new WSHttpBinding(),
new EndpointAddress("http://localhost:8732/Seller/"));
27
28varclient = factory.CreateChannel();
29
30if(client.Add(user, shop))
31Console.WriteLine("huangxincheng520, 恭喜你,数据插入成功。");
32else
33Console.WriteLine("huangxincheng520, 呜呜,数据插入失败。");
34
35Console.Read();
36}
37}
38}
最后就是测试了:
首先:走正常流程。client.Add方法调用服务器端,运行效果如图所示:
是的,数据已经正常插入成功,对Client端而言,这个操作是透明的。
然后:我们在Seller类中的Add方法中故意加入异常。看效果咋样。
1///
2///User,Shop的插入的操作
3///
4///
5///
6///
7[OperationBehavior(TransactionScopeRequired =true, TransactionAutoComplete =true)]
8publicboolAdd(Model.User user, Model.Shop shop)
9{
10intshopID;
11intUserID;
12
13if(Add(user,outUserID))
14{
15//注意注意,我在Adduser成功的情况下,抛出异常,看是否回滚。16throw new Exception();
17
18shop.UserID = UserID;
19
20returnAdd(shop,outshopID);
21}
22
23returnfalse;
24}
截图如下:
哈哈,抛出异常了,我的Exception起到效果了,再来看一下数据库。大家都知道会发生什么了,对的,异常不再产生数据了,
还是先前产生了那条数据,说明起到效果了。
作者:一线码农
原文地址:
https://www.cnblogs.com/huangxincheng/p/3815428.html
领取专属 10元无门槛券
私享最新 技术干货