小测试,WCF分布式事务的用法以及回滚条件 .

小测试,WCF分布式事务的用法以及回滚条件

分类: WCF服务 2009-07-16 10:48 1240人阅读 评论(3) 收藏 举报

 

Host1 宿主A

Host2 宿主B

Host3 宿主C

Client 客户端D

数据层

业务层

表现层

 

 

测试用例:宿主A、B、C皆是WCF服务。宿主A中方法F1访问数据库Db1,宿主B中方法F2访问数据库Db2,宿主C中方法F3调用F1和F2(按先F1后F2的顺序调用),客户端D调用宿主C的方法F3,完成一个业务流程。

 

关于分布式事务的用法

在宿主A、B中,([TransactionFlow(TransactionFlowOption.Allowed)])指示F1、F2方法接受客户端传入事务,并允许加入到流事务中,业务层将不再需要以using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))的形式来显式开启事务。

上例中,如果业务层宿主C的F3方法单独调用F1方法,则F1也会升级成为事务,事务由F1开启,虽然仅一步数据库操作。如果宿主C的F3方法单独调用F2方法,则同理。如果宿主C的F3方法同时调用F1、F2(按先F1后F2的顺序调用),则F1、F2合为一个分布式事务,事务将由F3开启,F1、F2自动加入事务,并在F3方法结束后结束事务。F3中加入的宿主A、B的方法理论上无上限,皆可组合成为一个新的分布式事务。之所以可以这样用是因为宿主C也是一个WCF服务,并开启了事务范围。如果把宿主C换成客户端D的F4方法去同时调用F1、F2方法,则该F4方法并不会启用分布式事务(就跟用webservers一样了)。

 

关于F3分布式事务的回滚条件

令F1正常运行,F2出现异常,讨论F1的回滚条件。

宿主C方法F3:

 

宿主C方法F3

宿主A方法F1

 

宿主B方法F2

 

CatchB

 

CatchA

宿主C方法F3

 

1、宿主C方法F3执行,F1执行成功,宿主B方法F2捕获到异常并且抛出,则宿主C方法F3的CatchA将捕获到异常,F3的CatchB没有捕获,客户端D也将捕获到异常:

 

此时F1方法的更新数据库操作被回滚,。

2、宿主C方法F3执行,F1执行成功,宿主B方法F2捕获到异常并且抛出,则宿主C方法F3的CatchA将捕获到异常(不抛出,情形同上),如果在宿主B方法F2的后面继续调用宿主B的其他方法,则F3的CatchB将捕获到异常:

,同时客户端D继续捕获到异常:

 

此时F1方法的更新数据库操作被回滚,。

3、宿主C方法F3执行,F1执行成功,宿主B方法F2捕获到异常并且抛出,则宿主C方法F3的CatchA将捕获到异常(情形同上),此时CatchA将捕获到的异常抛出: 则F3的CatchB也将捕获到异常(异常同上)。客户端D也将捕获到异常:

 

此时F1方法的更新数据库操作被回滚。

4、宿主C方法F3执行,F1执行成功,宿主B方法F2捕获到异常并且抛出,则宿主C方法F3的CatchA将捕获到异常(情形同上,CatchA不抛出),此时CatchB将捕获不到异常(抛不抛出就无所谓了)。客户端D仍将捕获到异常:

 

此时F1方法的更新数据库操作被回滚。(跟第一种情况是一样的,如果CatchA抛出,宿主B方法F2的后面继续调用宿主B的其他方法,则F3的CatchB将捕获到异常,此时跟第二种情况是一样的)。

 

5、宿主C方法F3执行,F1执行成功,宿主B方法F2捕获到异常不抛出,则宿主C方法F3的CatchA将捕获不到异常,F3的CatchB没有捕获,客户端D也将捕获不到异常:

此时F1方法的更新数据库操作不被回滚

 

数据层方法抛出就肯定会回滚了,不抛业务层客户端都没捕获,就不回滚了。。

 

 

 

 

 

WCF中常见的异常类型?

WCF包括三种常见类型的异常:

1) 通讯异常,这通常是因为链路的原因,比如服务没有启动,网络阻塞等。这类异常是CommunicationException或者其派生类

2) 状态异常,这类异常通常是与上文提到的实例模式相关的,当访问了一个已经销毁的服务器对象时便会引发此类型的异常,它们通常是ObjectDisposedException

3) 服务异常,由服务端根据具体的业务逻辑触发,通常是FaultException 值得注意的是当抛出服务异常的时候,不同的实例模式的处理方式有所不同:

PerSession:这种模式下,抛出异常,服务实例将销毁,客户端抛出FaultException,客户端代理对象无法继续使用

PerCall:这种模式下,抛出异常,服务实例也将销毁。客户端代理对象无法继续使用

Single:这种模式下,抛出异常,服务实例会照旧运行。客户端代理无法继续使用。

posted @ 2012-08-24 16:01  attitudedecidesall  Views(602)  Comments(0Edit  收藏  举报