最近在学WCF,所以有两个设想疑问(菜鸟多疑问):

  • 如果有WCF服务A,WCF服务B,客户端调用WCF服务A插入一条数据,然后再调用服务B也插入一条数据,然而服务B出错了进行了回滚,服务A能不能也进行回滚操作?
  • 或是客户端调用服务A和服务B,成功了插入了两条数据之后,客户端这边出错了,如何让服务A和服务B插入的数据也回滚操作?

经过学习探索,了解到WCF支持分布式事务,事务可以在多个服务中传播,也可以在服务端与客户端之间传播。

注:WCF内并非所有绑定都支持事务的,常用的BasicHttpBinding就不支持事务的传播。只有以下几个绑定才能支持事务流的运转:NetTcpBinding、WSHttpBinding、WSDualHttpBinding、WSFederationHttpBinding、NetNamedPipeBinding。

代码尝试

先建一个WCF服务(WSHttpBinding),有两个Add方法,在客户端两次分开调用

 [ServiceContract]
public interface IService1
{ [OperationContract]
string AddData_1(string a); [OperationContract]
string AddData_2(string a); }
 public class Service1 : IService1
{ [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
[TransactionFlow(TransactionFlowOption.Allowed)]
public string AddData_1(string b)
{
using (testEntities ts = new testEntities())
{
Student a = new Student()
{
Age = ,
Class = b,
Sex = "男",
Score =
};
ts.Student.Add(a);
ts.SaveChanges();
}
return "";
} [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
[TransactionFlow(TransactionFlowOption.Allowed)]
public string AddData_2(string b)
{
using (testEntities ts = new testEntities())
{
Student a = new Student()
{
Age = ,
Class = b,
Sex = "男",
Score =
};
ts.Student.Add(a);
ts.SaveChanges();
throw new Exception("出错拉!"); //抛出错误
} return "";
}
}

其中标红解释:

TransactionScopeRequired:值为true时,表示此WCF服务的方法中启动事务,为false,反之不启动。

TransactionAutoComplete:值为true时为隐式事务,方法在运行过程中没有抛出Exception,事务会自动提交。如果期间出现任何异常,事务就会自动回滚;false时,显式事务,必须OperationContext.Current.SetTransactionComplete () 显式提交事务。

TransactionFlowOption:设置为Allowed,开启事务传播,客户端的事务传播到服务端。

        有三个值:

      NotAllowed,禁止客户端传播事务流到服务端,即使客户端启动了事务,该事务也会被忽略;

        Allowed,允许客户端的事务传播到服务端,但服务器端不一定会引用到此事务(如果服务端方法没开启事务);

      Mandatory,服务端与客户端必须同时启动事务流,否则就会抛出InvalidOperationException异常。

web.config配置(重要)

服务端web.config

<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<!--启动事务流-->
<binding name="defaultWSHttpBinding" transactionFlow="true" />  <!--这里一定要设置绑定的transactionFlow为true,否则无法使用事务-->  

</wsHttpBinding>
</bindings> <behaviors>
<serviceBehaviors>
<behavior>
<!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false -->
<serviceMetadata httpGetEnabled="true" httpsGetEnabled="true" />
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息 -->
<serviceDebug includeExceptionDetailInFaults="false" />
</behavior>
</serviceBehaviors>
</behaviors>
<services>
<service name="WcfDemo_shiwu.Service1">
<endpoint address="" binding="wsHttpBinding"
contract="WcfDemo_shiwu.IService1" bindingConfiguration="defaultWSHttpBinding"/>  <!--这里一定要设置bindingConfiguration--> 
</service>
</services>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
</system.serviceModel>
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<!--
若要在调试过程中浏览 Web 应用程序根目录,请将下面的值设置为 True。
在部署之前将该值设置为 False 可避免泄露 Web 应用程序文件夹信息。
-->
<directoryBrowse enabled="true" />
</system.webServer>
</configuration>

客户端

<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/>
</startup>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_IService1" transactionFlow="true" />
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:5854/Service1.svc" binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_IService1" contract="TestService.IService1"
name="WSHttpBinding_IService1">
<identity>
<userPrincipalName value="DESKTOP-350R9O7\qiuguochao" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

客户端代码

情况一:WCF服务中的方法2报错回滚,那么之前第一次调用插入的是否成功回滚?

 static void Main(string[] args)
{
//客户端开启分布式事务,要引用System.Transactions.dll
using (TransactionScope ts = new TransactionScope())
{
//调用服务
using (TestService.Service1Client service = new TestService.Service1Client())
{
service.AddData_1(""); }
Console.WriteLine("第一次调用:成功插入一条数据");           //重新去调用WCF服务
using (TestService.Service1Client service2 = new TestService.Service1Client())
{
//WCF中的AddData_2会报错
service2.AddData_2(""); }
ts.Complete();
}
}

结果:

WCF服务插入第二条数据,已经报错,因为该方法中已经设置  [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)],开启了事务,所以第二数据肯定是会被回滚的

且看第一条数据是否也会被回滚?,结果是两条数据都被回滚了

情况2:两次调用WCF服务成功插入数据后,客户端报错回滚,在WCF服务中插入的数据是否也回滚?

将抛出错误注释掉,重新运行WCF服务

改写客户端代码,并设下断点:

执行到断点,查看数据情况

已经成功插入,继续执行,由于没有进行提交,所以该事务将会自动回滚,且看在WCF服务中插入的数据是否会被回滚

客户端进行了回滚操作,很显然,客户端的事务传播的WCF中的方法事务,也将相应的操作回滚。

WCF(三)分布式事务的更多相关文章

  1. WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程

    今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...

  2. 谈谈分布式事务之三: System.Transactions事务详解[上篇]

    在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集 ...

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

    今天是速成的第三天,再分享一下WCF中比较常用的一种技术,也就是”事务“. 在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表. 当然,要么插入 ...

  4. [转载]WCF系列_分布式事务(下)

    浏览到chnking的WCF的分布式事务处理不错,转载过来分享一下. 1. WCF分布式事务例子这里也用转账的例子说事.用户在系统A和系统B都有账户,账户间的资金可以互转,系统A的资金减少多少,系统B ...

  5. 三:分布式事务一致性协议2pc和3pc

    一:分布式一致性协议--->对于一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间进行反复的权衡,于是就产生了一系列的一致性协议.--->长期探索涌现出一大批经典的一 ...

  6. WCF分布式事务(EF)

    才说分布式事务,首先,了解一下什么是交易. 事务有四个特性:ACID A是Atomicity,原子性.一个事务往往涉及到很多的子操作,原子性则保证这些子操作要么都做,要么都不做,而不至于出现事务的部分 ...

  7. 分布式事务 & 两阶段提交 & 三阶段提交

    可以参考这篇文章: http://blog.csdn.net/whycold/article/details/47702133 两阶段提交保证了分布式事务的原子性,这些子事务要么都做,要么都不做. 而 ...

  8. 分布式事务(三)mysql对XA协议的支持

    系列目录 分布式事务(一)原理概览 分布式事务(二)JTA规范 分布式事务(三)mysql对XA协议的支持 分布式事务(四)简单样例 分布式事务(五)源码详解 分布式事务(六)总结提高 引子 从Mys ...

  9. 分布式事务专题笔记(三)分布式事务解决方案之TCC(三阶段提交)

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.什么是TCC事务 TCC是Try.Confifirm.Cancel三个词语的缩写,TCC要求每个分支 ...

随机推荐

  1. Python网络数据采集6-隐含输入字段

    Python网络数据采集6-隐含输入字段 selenium的get_cookies可以轻松获取所有cookie. from pprint import pprint from selenium imp ...

  2. 1059. C语言竞赛

    C 语言竞赛是浙江大学计算机学院主持的一个欢乐的竞赛.既然竞赛主旨是为了好玩,颁奖规则也就制定得很滑稽: 冠军将赢得一份"神秘大奖"(比如很巨大的一本学生研究论文集--). 排名为 ...

  3. Python 发展历史

    1. Python发展历史 起源 Python的作者,Guido von Rossum,荷兰人.1982年,Guido从阿姆斯特丹大学获得了数学和计算机硕士学位.然而,尽管他算得上是一位数学家,但他更 ...

  4. 超超超简单的bfs——POJ-1915

    Knight Moves Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 26102   Accepted: 12305 De ...

  5. akoj-1267-独木舟上的荡漾

    独木舟上的荡漾 Time Limit:1000MS  Memory Limit:65536K Total Submit:76 Accepted:44 Description 进行一次独木舟的旅行活动, ...

  6. 手脱UPX(堆栈平衡原理)

    一开始看到pushad F8执行直到只有esp,eip,变化 在esp处follow in dump 下硬件访问断点 F9运行在硬件断点停下 到达一个长跳转(跳到OEP) 完成 ----------- ...

  7. 一个普通的 Zepto 源码分析(一) - ie 与 form 模块

    一个普通的 Zepto 源码分析(一) - ie 与 form 模块 普通的路人,普通地瞧.分析时使用的是目前最新 1.2.0 版本. Zepto 可以由许多模块组成,默认包含的模块有 zepto 核 ...

  8. [算法题] Remove Duplicates from Sorted Array

    题目内容 本题来源于LeetCode Given a sorted array, remove the duplicates in place such that each element appea ...

  9. angular学习(二)-- Directive

    1.2 指令:Directive AngularJS 通过被称为 指令 的新属性来扩展 HTML, 具体表现形式一般为带有前缀 ng-xxx 的 HTML 属性. 指令的使用形式 ng-xxx 的属性 ...

  10. JavaScript基础知识(二)

    一.JavaScript事件详解 1.事件流:描述的是在页面中结束事件的顺序 事件传递有两种方式:冒泡与捕获. 事件传递定义了元素事件触发的顺序. 如果你将 <p> 元素插入到 <d ...