WCF技术剖析之三十一:WCF事务编程[上篇]
2010-03-11 18:48
716 查看
WCF事务编程其实很简单,可以用三句话进行概括:通过服务契约决定事物流转(Transaction Flow)的策略;通过绑定实施事务的流转;通过服务行为控制事务的相关行为。本篇文章着重介绍如果通过TransactionFlowAttribute特性定义事务流转策略。
契约时是一种双边协定,是双方就某个关注点达成的一种共识。对于分布式事务的实现来讲,首先需要解决的是事务流转的问题,即事务将客户端的事务流向服务端。要解决事务流转的问题,需要在事务的发送方和接收方就流转问题达成共识,即双方采用相匹配的事务发送和接收策略。毫无疑问,这样的开关需要定义在服务契约之上,同时事务是基于服务操作的,所以事务流转策略最终应用到操作契约上面。
WCF通过TransactionFlowAttribute特性将相应的事务流转策略关联到某个服务之上,具体来讲,我们在定义服务契约的时候,直接将TransactionFlowAttribute特性应用到相应的操作契约上即可。我们先来看看TransactionFlowAttribute的定义,从下面的代码我们可以看到,TransactionFlowAttribute并仅仅是一个简单的自定义特性,它更是一个操作行为。至于该操作行为对事务流转行为作了怎样的控制,会在后续的文章详细讲述。
当我们将TransactionFlowAttribute特性应用到操作契约的时候,具体事务流转策略通过TransactionFlowOption枚举指定,TransactionFlowOption定义如下。
TransactionFlowOption一共定义了三选项:NotAllowed、Allowed和Mandatory,它们的分别代表的事务流转策略如下:
NotAllowed:客户端的事务不允许被流转到服务端;服务端也不会试图去接收流入的事务,这是默认选项;
Allowed:如果客户端事务存在,则被流转到服务端;服务端会试图去接收流入的事务;
Mandatory:客户端必须在一个事务中进行服务调用,相应的事务并会被流转到服务端;服务端接收到的消息中必须包含被序列化的事务。
在下面定义的IBankingService服务契约中,我们将TransactionFlowAttribute特性应用到了用于进行转帐操作的Transfer方法之上,并指定事务流转选项为Mandatory。
对于Mandatory选项,如果客户端在进行服务调用的时候并不存在事务,或者说服务端并没有接收到任何流入的事务(当客户端和服务端采用的契约定义了不匹配的事务流转策略时会出现这种情况下,比如客户端采用NotAllowed选项,客户端则采用Mandatory,那么服务端永远也接收不到流入的事务),都会抛出如图1所示的ProtocolException异常。
图1 在选用Mandatory选项下客户端不存在事务导致的异常
事务从客户端流转到服务端后,服务端可以中止事务,并将结果返回到客户端。从这个意义上讲,事务流转建立在请求/回复消息交换模式(MEP)之上,所以,在一个单向(One-Way)操作契约上,不允许应用TransactionFlowAttribute并指定Allowed或者Mandatory选项。比如下面的服务契约定义是不合法的:
如果某个服务实现了这样的服务契约,在进行服务寄宿的时候,会抛出如图2所示的InvalidOperationException异常(如果仔细的话还会看到VS一个汉化的问题:“单项”应该是“单向”,呵呵!!)。
图2 在单向操作上应用TransactionFlowAttribute特性导致的异常
契约时是一种双边协定,是双方就某个关注点达成的一种共识。对于分布式事务的实现来讲,首先需要解决的是事务流转的问题,即事务将客户端的事务流向服务端。要解决事务流转的问题,需要在事务的发送方和接收方就流转问题达成共识,即双方采用相匹配的事务发送和接收策略。毫无疑问,这样的开关需要定义在服务契约之上,同时事务是基于服务操作的,所以事务流转策略最终应用到操作契约上面。
WCF通过TransactionFlowAttribute特性将相应的事务流转策略关联到某个服务之上,具体来讲,我们在定义服务契约的时候,直接将TransactionFlowAttribute特性应用到相应的操作契约上即可。我们先来看看TransactionFlowAttribute的定义,从下面的代码我们可以看到,TransactionFlowAttribute并仅仅是一个简单的自定义特性,它更是一个操作行为。至于该操作行为对事务流转行为作了怎样的控制,会在后续的文章详细讲述。
[AttributeUsage(AttributeTargets.Method)] public sealed class TransactionFlowAttribute : Attribute, IOperationBehavior { //其他成员 public TransactionFlowAttribute(TransactionFlowOption transactions); public TransactionFlowOption Transactions { get; } }
当我们将TransactionFlowAttribute特性应用到操作契约的时候,具体事务流转策略通过TransactionFlowOption枚举指定,TransactionFlowOption定义如下。
public enum TransactionFlowOption { NotAllowed, Allowed, Mandatory }
TransactionFlowOption一共定义了三选项:NotAllowed、Allowed和Mandatory,它们的分别代表的事务流转策略如下:
NotAllowed:客户端的事务不允许被流转到服务端;服务端也不会试图去接收流入的事务,这是默认选项;
Allowed:如果客户端事务存在,则被流转到服务端;服务端会试图去接收流入的事务;
Mandatory:客户端必须在一个事务中进行服务调用,相应的事务并会被流转到服务端;服务端接收到的消息中必须包含被序列化的事务。
在下面定义的IBankingService服务契约中,我们将TransactionFlowAttribute特性应用到了用于进行转帐操作的Transfer方法之上,并指定事务流转选项为Mandatory。
[ServiceContract(Namespace = "http://www.artech.com/")] public interface IBankingService { [OperationContract] [TransactionFlow(TransactionFlowOption.Mandatory)] void Transfer(string accountFrom, string accountTo, double amount); }
对于Mandatory选项,如果客户端在进行服务调用的时候并不存在事务,或者说服务端并没有接收到任何流入的事务(当客户端和服务端采用的契约定义了不匹配的事务流转策略时会出现这种情况下,比如客户端采用NotAllowed选项,客户端则采用Mandatory,那么服务端永远也接收不到流入的事务),都会抛出如图1所示的ProtocolException异常。
图1 在选用Mandatory选项下客户端不存在事务导致的异常
事务从客户端流转到服务端后,服务端可以中止事务,并将结果返回到客户端。从这个意义上讲,事务流转建立在请求/回复消息交换模式(MEP)之上,所以,在一个单向(One-Way)操作契约上,不允许应用TransactionFlowAttribute并指定Allowed或者Mandatory选项。比如下面的服务契约定义是不合法的:
[ServiceContract(Namespace = "http://www.artech.com/")] public interface IBankingService { [OperationContract(IsOneWay = true)] [TransactionFlow(TransactionFlowOption.Mandatory)] void Transfer(string accountFrom, string accountTo, double amount); }
如果某个服务实现了这样的服务契约,在进行服务寄宿的时候,会抛出如图2所示的InvalidOperationException异常(如果仔细的话还会看到VS一个汉化的问题:“单项”应该是“单向”,呵呵!!)。
图2 在单向操作上应用TransactionFlowAttribute特性导致的异常
相关文章推荐
- WCF技术剖析之三十一: WCF事务编程[下篇]
- WCF技术剖析之三十一: WCF事务编程[中篇]
- WCF技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[上篇]
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[上篇]
- [原创] WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[上篇]
- WCF 技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[下篇]
- [原创]WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(上篇)
- [原创]WCF技术剖析之二十一: WCF基本的异常处理模式[上篇]
- [原创]WCF技术剖析之十一:异步操作在WCF中的应用(上篇)
- WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(上篇)
- WCF技术剖析之二十一: WCF基本的异常处理模式[上篇]
- WCF技术剖析之十四:泛型数据契约和集合数据契约(上篇)
- WCF技术剖析之二十二: 深入剖析WCF底层异常处理框架实现原理[上篇]
- WCF技术剖析之十四:泛型数据契约和集合数据契约(上篇)
- WCF技术剖析之十九:深度剖析消息编码(Encoding)实现(上篇)
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]
- WCF技术剖析之十一:异步操作在WCF中的应用(上篇)
- WCF技术剖析之十七:消息(Message)详解(上篇)
- WCF技术剖析之三十:一个很有用的WCF调用编程技巧[下篇]