最近在学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. 压缩[SCOI2007]

    题目描述 给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息.压缩后的字符串除了小写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前 ...

  2. 又见angular----步一步做一个angular4小项目

    这两天看了看angular4的文档,发现他和angular1.X的差别真的是太大了,官方给出的那个管理英雄的Demo是一个非常好的入门项目,这里给出一个管理个人计划的小项目,从头至尾一步一步讲解如何去 ...

  3. 蓝桥杯算法训练_2的次幂表示+前缀表达式+Anagrams问题+出现次数最多的整数

    今天做了4个简单的题,题目虽然是简单,但是对于我这样的小白,还是有很多东西需要学习的. 2的次幂表示 上面就是题目,题目说的也很清晰了,接下来就是递归的实现: #include<iostream ...

  4. HTML——CSS的基础语法1

    页面中所有CSS代码,需要写入到<style></style>标签中. style标签的type属性应该选择text/css,但是type属性可以省略. 1.CSS常用选择器 ...

  5. [Scoi2014]方伯伯的玉米田 二维树状数组+动态规划

    考试最后半个小时才做这道题.十分钟写了个暴力还写挂了..最后默默输出n.菜鸡一只. 这道题比较好看出来是动规.首先我们要明确一点.因为能拔高长度任意的一段区域,所以如果从i开始拔高,那么一直拔高到n比 ...

  6. Java微信公众平台开发之扫码支付模式二

    官方文档点击查看 准备工作:已通过微信认证的公众号,域名可以不通过ICP备案借鉴了很多大神的文章,在此先谢过了大体过程:根据固定金额和商品的ID先生成订单,再生成二维码,客户扫一扫付款模式二支付的流程 ...

  7. Linux - 简明Shell编程01 - 第一个脚本(HelloShell)

    脚本地址 https://github.com/anliven/L-Shell/tree/master/Shell-Basics 示例脚本及注释 #!/bin/bash echo "hell ...

  8. VMvare 虚拟网卡vmnet1 and vmnet8

    VMvare 虚拟网卡vmnet1 and vmnet8---------------------------------2013/11/03 在使用VMware Workstation创建虚拟机时, ...

  9. 使用VIEWER.JS进行简单的图片预览

    <script src="../res/js/viewer.min.js"></script><script type="text/java ...

  10. Python 一等函数

    p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 15.0px Helvetica } 在 Python 中,函数是一等对象.编程语言理论家把"一等 ...