WCF(三)分布式事务
最近在学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(三)分布式事务的更多相关文章
- WCF分布式开发步步为赢(12):WCF事务机制(Transaction)和分布式事务编程
今天我们继续学习WCF分布式开发步步为赢系列的12节:WCF事务机制(Transaction)和分布式事务编程.众所周知,应用系统开发过程中,事务是一个重要的概念.它是保证数据与服务可靠性的重要机制. ...
- 谈谈分布式事务之三: System.Transactions事务详解[上篇]
在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集 ...
- wcf系列学习5天速成——第三天 事务的使用
今天是速成的第三天,再分享一下WCF中比较常用的一种技术,也就是”事务“. 在B2B的项目中,一般用户注册后,就有一个属于自己的店铺,此时,我们就要插入两张表, User和Shop表. 当然,要么插入 ...
- [转载]WCF系列_分布式事务(下)
浏览到chnking的WCF的分布式事务处理不错,转载过来分享一下. 1. WCF分布式事务例子这里也用转账的例子说事.用户在系统A和系统B都有账户,账户间的资金可以互转,系统A的资金减少多少,系统B ...
- 三:分布式事务一致性协议2pc和3pc
一:分布式一致性协议--->对于一个分布式系统进行架构设计的过程中,往往会在系统的可用性和数据一致性之间进行反复的权衡,于是就产生了一系列的一致性协议.--->长期探索涌现出一大批经典的一 ...
- WCF分布式事务(EF)
才说分布式事务,首先,了解一下什么是交易. 事务有四个特性:ACID A是Atomicity,原子性.一个事务往往涉及到很多的子操作,原子性则保证这些子操作要么都做,要么都不做,而不至于出现事务的部分 ...
- 分布式事务 & 两阶段提交 & 三阶段提交
可以参考这篇文章: http://blog.csdn.net/whycold/article/details/47702133 两阶段提交保证了分布式事务的原子性,这些子事务要么都做,要么都不做. 而 ...
- 分布式事务(三)mysql对XA协议的支持
系列目录 分布式事务(一)原理概览 分布式事务(二)JTA规范 分布式事务(三)mysql对XA协议的支持 分布式事务(四)简单样例 分布式事务(五)源码详解 分布式事务(六)总结提高 引子 从Mys ...
- 分布式事务专题笔记(三)分布式事务解决方案之TCC(三阶段提交)
个人博客网:https://wushaopei.github.io/ (你想要这里多有) 1.什么是TCC事务 TCC是Try.Confifirm.Cancel三个词语的缩写,TCC要求每个分支 ...
随机推荐
- 定时任务FluentScheduler 学习笔记 .net
第一步添加引用 GitHub源码地址 与详细用法 https://github.com/fluentscheduler/FluentScheduler 下面开始简单的实现 /// <summar ...
- C++写#pragma warning(disable 4786)的作用
C++编程时,在使用STL(C++标准模板库)的时候经常引发类似的错误,尤其是vector,map这类模板类,模板中套模板,一不小心就很长了. 当命名超过C++规定范围255字符时,就会产生这个名为d ...
- 再起航,我的学习笔记之JavaScript设计模式03
我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 上一 ...
- JAVA,JSP,Servlet获取当前工程路径-绝对路径
在jsp和class文件中调用的相对路径不同. 在jsp里,根目录是WebRoot 在class文件中,根目录是WebRoot/WEB-INF/classes 当然你也可以用System.getPro ...
- 笨办法用js屏蔽被http劫持的浮动广告
最近发现网站经常在右下角弹出一个浮动广告,开始的时候以为只是浏览器的广告. 后来越来越多同事反映在家里不同浏览器也会出现广告.然后深入检查了下,发现网站竟然被劫持了. 然后百度了一大堆资料,什么htt ...
- mysql 触发器(trigger)
触发器(trigger):监视某种情况,并触发某种操作. 触发器创建语法四要素:1.监视地点(table) 2.监视事件(insert/update/delete) 3.触发时间(after/befo ...
- 王佩丰第2讲-excel单元格格式设置 笔记
点小箭头都可以进入单元格格式设置 跨越合并 添加斜线 回车 ALT+ENTER 格式刷 数字格式 特定红色 货币VS会计专用 日期 2是1月2号,3是1月3号-- 自定义[例子中是在数值后面加&quo ...
- Windows开发笔记-错误处理
Windows函数为开发者提供了错误代码,这样当调用Windows函数失败后,可以通过查看错误代码了解错误信息.相应的错误与主调线程关联在一起,这种机制使得不同的线程能够独立运行而不会相互干扰.调用G ...
- instanceof问题
java 中的instanceof 运算符是用来在运行时指出对象是否是特定类的一个实例.instanceof通过返回一个布尔值来指出,这个对象是否是这个特定类或者是它的子类的一个实例. 用法:resu ...
- C++11 中值得关注的几大变化(网摘)
C++11 中值得关注的几大变化(详解) 原文出处:[陈皓 coolshell] 源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 ...