在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事务应用[转]的更多相关文章

  1. WCF入门(十)---WCF事务

    事务处理在WCF(Windows Communication Foundation)是一套遵循一些性质,统称为ACID的操作.这里,如果一个操作出现故障,整个系统就会自动失败.如网上订单生成,就可能使 ...

  2. wcf事务(随记)

    ----------------------------------------------------wcf事务:1.ACID:原子性.一致性.隔离性.持久性:2.事务:添加命名空间(using S ...

  3. WCF学习笔记之事务编程

    WCF学习笔记之事务编程 一:WCF事务设置 事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元: WCF通过System.ServiceModel.TransactionFlowA ...

  4. 跟我一起学WCF(13)——WCF系列总结

    引言 WCF是微软为了实现SOA的框架,它是对微乳之前多种分布式技术的继承和扩展,这些技术包括Enterprise Service..NET Remoting.XML Web Service.MSMQ ...

  5. 跟我一起学WCF(10)——WCF中事务处理

    一.引言 好久没更新,总感觉自己欠了什么一样的,所以今天迫不及待地来更新了,因为后面还有好几个系列准备些,还有很多东西需要学习总结的.今天就来介绍下WCF对事务的支持. 二.WCF事务详解 2.1 事 ...

  6. 快速入门系列--WCF--06并发限流、可靠会话和队列服务

    这部分将介绍一些相对深入的知识点,包括通过并发限流来保证服务的可用性,通过可靠会话机制保证会话信息的可靠性,通过队列服务来解耦客户端和服务端,提高系统的可服务数量并可以起到削峰的作用,最后还会对之前的 ...

  7. [WCF编程]12.事务:服务事务编程(下)

    一.投票与提交 虽然WCF负责事务传播及两阶段提交协议的管理工作,但是 她不知道事务是否应该提交或终止.这需要根服务告诉WCF应该何时启动两阶段提交协议.是提交还是终止.WCF提供了两种编程模式来对事 ...

  8. [WCF编程]12.事务:服务事务编程(上)

    一.设置环境事务 默认情况下,服务类和操作没有环境事务,即使客户端事务传播到服务端也是如此. 尽管强制事务流从客户端传播过来,但服务端的环境事务依旧为null.为了启用环境事务,每个操作必须告诉WCF ...

  9. [WCF编程]12.事务:事务传播

    一.事务传播概述 WCF可以跨越服务边界传递事务.这可以让服务参与到客户端事务里,客户端还可以在同一个事务里调用多个服务.客户端本身不一定是WCF服务.客户端事务是否传播到服务端可以通过绑定和操作契约 ...

随机推荐

  1. 文件权限:普通(r、w、x)和特殊(s、t)

     linux中,常常涉及到权限的问题.文件的权限有3组,owner,group,other,每一组都有rwx三种设置.r(4):可读:w(2):可写:x(1):可执行.我们在执行shell命令ls - ...

  2. iOS解析XML数据

    iOS中解析XML数据的类是  NSXMLParser,详细使用方法如下: 假设现在在内存中有XML的二进制数据对象(NSData):data(该数据可能来自网络,也可能是本地的文件数据),设置NSX ...

  3. Sublime Text 3 汉化小技巧

    Sublime Text 3 简体中文汉化包使用方法 1.将下载的sublime_text3汉化包文件解压,得到的Default.sublime-package 文件.打开sublime text 3 ...

  4. ZooKeeper日志与快照文件简单分析

    有用过Zookeeper的都知道zoo.cfg配置文件中有dataDir配置项用于存储数据,不过可能有些人不太清楚这个目录具体存储的是那些数据,默认情况下这个目录是用于存储Log(事务日志)与Snap ...

  5. cuda fft 计算

    #include <assert.h> #include <stdio.h> #include <stdlib.h> #include <string.h&g ...

  6. curl/wget 测试http请求的响应头信息

    1. wget –debug wget可以使用debug信息来查看信息头,如下: [root@localhost ~]# wget --debug http://192.168.1.101:8080/ ...

  7. C++/MFC如何启动另一个应用程序并获取其进程 ID

    ShellExecute( hWnd: HWND; {指定父窗口句柄} Operation: PChar; {指定动作, 譬如: open.runas.print.edit.explore.find[ ...

  8. 自动SPF生成工具

    到openspf网站去自动生成一下,地址是http://old.openspf.org/wizard.html.详细解释见下图关于spf的详细语法请看http://www.openspf.org/SP ...

  9. [翻译]观察变换View Transform (Direct3D 9)

    这一节介绍在Direct3d中观察变换的基本概念和怎么去设置观察矩阵. 视口变换把观察者放在世界坐标系中,并把顶点转化到摄像机空间.在摄像机空间,摄像机或者说观察者在原点,观察方向为z轴正向.Dire ...

  10. 转!!java反射机制

    Java 反射机制 基本概念 在Java运行时环境中,对于任意一个类,能否知道这个类有哪些属性和方法?对于任意一个对象,能否调用它的任意一个方法? 答案是肯定的. 这种动态获取类的信息以及动态调用对象 ...