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="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起到效果了,再来看一下数据库。大家都知道会发生什么了,对的,异常不再产生数据了,
还是先前产生了那条数据,说明起到效果了。
WCF事务应用[转]的更多相关文章
- WCF入门(十)---WCF事务
事务处理在WCF(Windows Communication Foundation)是一套遵循一些性质,统称为ACID的操作.这里,如果一个操作出现故障,整个系统就会自动失败.如网上订单生成,就可能使 ...
- wcf事务(随记)
----------------------------------------------------wcf事务:1.ACID:原子性.一致性.隔离性.持久性:2.事务:添加命名空间(using S ...
- WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程
今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...
- wcf事务
wcf服务 using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serial ...
- WCF学习笔记之事务编程
WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...
- WCF基础之事务
说到事务,我最先想到的是“回滚”. 百科:事务是恢复和并发控制的基本单位.事务应该具有4个属性:原子性.一致性.隔离性.持久性.这四个属性通常称为ACID特性.好了,具体的就不多复制了. 我小试了一下 ...
- 跟我一起学WCF(13)——WCF系列总结
引言 WCF是微软为了实现SOA的框架,它是对微乳之前多种分布式技术的继承和扩展,这些技术包括Enterprise Service..NET Remoting.XML Web Service.MSMQ ...
- 跟我一起学WCF(10)——WCF中事务处理
一.引言 好久没更新,总感觉自己欠了什么一样的,所以今天迫不及待地来更新了,因为后面还有好几个系列准备些,还有很多东西需要学习总结的.今天就来介绍下WCF对事务的支持. 二.WCF事务详解 2.1 事 ...
- C#综合揭秘——细说事务
引言 其实事务在数据层.服务层.业务逻辑层多处地方都会使用到,在本篇文章将会为大家一一细说. 其中前面四节是事务的基础,后面的三节是事务的重点,对事务有基础的朋友可以跳过前面四节. 文章有错漏的地方欢 ...
随机推荐
- oauth协议
微博 : 新浪 腾讯 OAuth 新浪微博 APP开发 步骤:1.注册新浪开发者账号 获取以下信息 client_id 123456 标示应用身份的 唯一的 有的也叫App Key sec ...
- 使用 gulp 搭建前端环境入门篇(转载)
本文转载自: 使用 gulp 搭建前端环境入门篇
- poj 1888 Crossword Answers 模拟题
Crossword Answers Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 869 Accepted: 405 D ...
- Ugly Number
public class Solution { public bool IsUgly(int num) { ) return false; ) return true; *==num){ num = ...
- mysql查询优化器的提示(hit)
如果对优化器选择的执行计划不满意,可以使用优化器提供的几个提示来控制最终的执行计划,关于每个提示的具体用法,建议直接阅读官方手册,一些提示和版本有直接关系,可以使用的一些提示如下: high_prio ...
- 1350. Primary Arithmetic
Children are taught to add multi-digit numbers from right-to-left one digit at a time. Many find th ...
- cf 700 B Connecting Universities
题意:现在给以一棵$n$个结点的树,并给你$2k$个结点,现在要求你把这些节点互相配对,使得互相配对的节点之间的距离(路径上经过边的数目)之和最大.数据范围$1 \leq n \leq 200000, ...
- 2015弱校联盟(1) -J. Right turn
J. Right turn Time Limit: 1000ms Memory Limit: 65536KB frog is trapped in a maze. The maze is infini ...
- SQL SA密码丢失
------------记不清了,以下似乎是这样操作的-----NET STOP MSSQLSERVER Net Start MSSQLServer /m"SQLCMD" 安装并使 ...
- CentOS7 基础配置
Centos 7 部分>>>>>>>>>>>>>>>>>>>>>>& ...