mysql分布式事务wcf_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 interfaceIService1

{

[OperationContract]string AddData_1(stringa);

[OperationContract]string AddData_2(stringa);

}

public classService1 : IService1

{

[OperationBehavior(TransactionScopeRequired= true, TransactionAutoComplete = true)]

[TransactionFlow(TransactionFlowOption.Allowed)]public string AddData_1(stringb)

{using (testEntities ts = newtestEntities())

{

Student a= newStudent()

{

Age= 9999999,

Class=b,

Sex= "男",

Score= 100};

ts.Student.Add(a);

ts.SaveChanges();

}return "22222";

}

[OperationBehavior(TransactionScopeRequired= true, TransactionAutoComplete = true)]

[TransactionFlow(TransactionFlowOption.Allowed)]public string AddData_2(stringb)

{using (testEntities ts = newtestEntities())

{

Student a= newStudent()

{

Age= 9999999,

Class=b,

Sex= "男",

Score= 100};

ts.Student.Add(a);

ts.SaveChanges();throw new Exception("出错拉!"); //抛出错误

}return "22222";

}

}

其中标红解释:

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

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

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

有三个值:

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

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

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

web.config配置(重要)

服务端web.config

客户端

bindingConfiguration="WSHttpBinding_IService1" contract="TestService.IService1"name="WSHttpBinding_IService1">

客户端代码

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

static void Main(string[] args)

{//客户端开启分布式事务,要引用System.Transactions.dll

using (TransactionScope ts = newTransactionScope())

{//调用服务

using (TestService.Service1Client service = newTestService.Service1Client())

{

service.AddData_1("1");

}

Console.WriteLine("第一次调用:成功插入一条数据");

//重新去调用WCF服务using (TestService.Service1Client service2 = newTestService.Service1Client())

{//WCF中的AddData_2会报错

service2.AddData_2("2");

}

ts.Complete();

}

}

结果:

8b9d4a6bf54ec8ec473670dc04f257dace8.jpg

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

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

2bcb771c3240a3242d009fcda41792a9acb.jpg

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

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

efe689aff610f59b935587640112cf62669.jpg

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

7fe54ed20f65c494333d474db0150a05e6b.jpg

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

0245886315b166adaa137529f0a1fb1158e.jpg

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

490b149efc4338d00de8ba3ab8520d28943.jpg

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值