Windows Communication Foundation (WCF)提供高度灵活的选项来控制事务流。 可以使用属性和配置的组合来表示服务的事务流设置。
事务流设置
由于以下三个值的交集,为服务终结点生成事务流设置:
TransactionFlowAttribute为服务协定中的每个方法指定的属性。
特定绑定中的
TransactionFlow
绑定属性。特定绑定中的
TransactionFlowProtocol
绑定属性。 通过TransactionFlowProtocol
绑定属性,可以在可用于流事务的两种不同事务协议之间进行选择。 以下各节简要介绍了每个部分。
WS-AtomicTransaction 协议
WS-AtomicTransaction(WS-AT)协议适用于需要与第三方协议堆栈的互作性的方案。
OleTransactions 协议
当不需要与第三方协议堆栈的互作性时,OleTransactions 协议非常有用,并且服务部署者事先知道本地禁用了 WS-AT 协议服务,或者现有网络拓扑不支持使用 WS-AT。
下表显示了可以使用这些各种组合生成的不同类型的事务流。
TransactionFlow 约束 |
TransactionFlow 绑定属性 | TransactionFlowProtocol 绑定协议 | 事务流的类型 |
---|---|---|---|
强制的 | 是 | WS-AT | 交易必须以可互操作 WS-AT 格式进行。 |
强制的 | 是 | OleTransactions | 事务必须以 WCF OleTransactions 格式流动。 |
强制的 | 假 | 不適用 | 不适用,因为这是无效的配置。 |
允许 | 是 | WS-AT | 事务可以采用可互作 WS-AT 格式进行流式处理。 |
允许 | 是 | OleTransactions | 事务可以采用 WCF OleTransactions 格式流动。 |
允许 | 假 | 任何值 | 不流动事务。 |
不允许 | 任何值 | 任何值 | 不流动事务。 |
下表汇总了消息处理结果。
传入消息 | TransactionFlow 设置 | 事务标头 | 消息处理结果 |
---|---|---|---|
事务匹配预期协议格式 | 允许或必须 |
MustUnderstand 等于 true 。 |
流程 |
事务与预期的协议格式不匹配 | 强制的 |
MustUnderstand 等于 false 。 |
因要求一个事务而拒绝 |
事务与预期的协议格式不匹配 | 允许 |
MustUnderstand 等于 false 。 |
因无法理解标头而拒绝 |
使用任何协议格式的事务 | 不允许 |
MustUnderstand 等于 false 。 |
因无法理解标头而拒绝 |
无交易 | 强制的 | 无 | 因要求一个事务而拒绝 |
无交易 | 允许 | 无 | 流程 |
无交易 | 不允许 | 无 | 流程 |
虽然合同上的每个方法可以有不同的事务流要求,但事务流协议设置的范围是在绑定级别。 这意味着共享同一终结点的所有方法(因此同一绑定)也共享允许或需要事务流的相同策略,以及相同的事务协议(如果适用)。
在方法级别启用事务流
对于服务协定中的所有方法,事务流要求并非总是相同。 因此,WCF 还提供了一种基于属性的机制,允许表达每个方法的事务流首选项。 这是通过TransactionFlowAttribute指定服务操作接受事务标头的级别来实现的。 如果要启用事务流,则应使用此属性标记服务协定方法。 此属性采用枚举的值 TransactionFlowOption 之一,其中默认值为 NotAllowed。 如果指定了除了NotAllowed之外的任何值,则该方法必须不是单向的。 开发人员可以使用此属性在设计时指定方法级事务流要求或约束。
在终结点级别启用事务流
除了属性提供的方法级事务流设置 TransactionFlowAttribute 外,WCF 还提供事务流的终结点范围设置,以允许管理员控制更高级别的事务流。
这是通过 TransactionFlowBindingElement它来实现的,这使你可以在终结点的绑定设置中启用或禁用传入事务流,以及为传入事务指定所需的事务协议格式。
如果绑定已禁用事务流,但服务协定中的某个操作需要传入事务,则在服务启动时会引发验证异常。
WCF 提供的大多数现有绑定包含transactionFlow
transactionProtocol
属性,使你可以配置特定绑定以接受传入事务。 有关设置配置元素的详细信息,请参阅 <绑定>。
管理员或部署程序可以使用终结点级事务流来使用配置文件在部署时配置事务流要求或约束。
安全
为了确保系统安全性和完整性,必须在应用程序之间流动事务时保护消息交换。 不应将事务详细信息流式处理或披露给任何无权参与同一事务的应用程序。
在使用元数据交换向未知或不受信任的 Web 服务生成 WCF 客户端时,对这些 Web 服务上的操作的调用应取消当前的事务(如可能)。 以下示例演示如何执行此操作。
//client code which has an ambient transaction
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
{
// No transaction will flow to this operation
untrustedProxy.Operation1(...);
scope.Complete();
}
//remainder of client code
此外,应将服务配置为仅接受已进行身份验证和授权的客户端的传入事务。 仅当传入事务来自高度受信任的客户端时,才应接受这些事务。
策略断言
WCF 使用策略断言来控制事务流。 可以在服务的策略文档中找到策略断言,该文档是通过聚合协定、配置和属性生成的。 客户端可以使用 HTTP GET 或 WS-MetadataExchange 请求-回复来获取服务的策略文档。 然后,客户端可以处理政策文档,以确定服务合同中的哪些操作可能支持或需要事务流。
事务流策略断言通过指定客户端应发送给服务以表示事务的 SOAP 标头来影响事务流。 所有事务标头必须标记为 MustUnderstand
等于 true
。 以其他方式标记标头的任何消息都将被拒绝,并出现 SOAP 错误。
在单个操作上只能存在一个与事务相关的策略断言。 在一个操作上具有多个事务断言的策略文档将被视为无效,并且将被 WCF 拒绝。 此外,每个端口类型中只能存在单个事务协议。 引用单个端口类型内多个事务协议的策略文档被视为无效, ServiceModel 元数据实用工具工具(Svcutil.exe)拒绝。 输出消息或单向输入消息上存在的事务断言的策略文档也被视为无效。