WCF 技术剖析之三十三:你是否了解WCF事务框架体系内部的工作机制?[下篇]

简介:

[续《上篇》]TransactionFlow选项通过TransactionFlowAttribute这个操作契约写入绑定上下文,由事务绑定创建的事务信道获取该选项并以此作为首否对事务实施传播(发送或者接收)的依据。客户端事务信道通过TransactionFormatter对当前事务按照指定的事务处理协议进行格式化,并嵌入出栈消息;通过TransactionFormatter则从入栈消息中提取相应的数据重建事务。这就是事务流转实现的本质。整个WCF事务还有一个重要的步骤需要实现:如何将通过OperationBehaviorAttribute特性标记为TransactionRequired的操作的执行自动纳入到流入的事务之中。接下来,我们就来着重讨论这个问题。

一、 事务的自动登记(Enlistment)

被格式化的事务最终是作为一个消息报头(MessageHeader)的形式被传输的。服务端事务信道接接收到包含有流入事务的消息后,按照指定的协议从相应的报头中获取将被格式化的事务获取出来,并通过TransactionFormatter对事务进行重新创建。被重新创建的事务对象最终以消息属性(MessageProperty)的形式重新放入入栈消息。

这样一个包含有事务对象的消息属性定义在一个类型为TransactionMessageProperty对象之中,TransactionMessageProperty定义如下。只读属性Transaction获取内嵌于消息属性对象的事务,而静态方法Set则将事务作为消息属性植入指定的消息。该消息属性在消息中的Key为TransactionMessageProperty,即类型的名称。

   1: public sealed class TransactionMessageProperty
   2: {
   3:     //其他成员
   4:     public static void Set(Transaction transaction, Message message);
   5:     public Transaction Transaction { get; }
   6: }

WCF运行时根据消息的Action报头定位到相应的操作,如果该操作应用了OperationBehaviorAttribute特性并将TransactionRequired属性设为True,会进行如下的操作:

  • 如果入栈消息中包含事务消息属性,则提取事务并基于该事务创建TransactionScope对象。TransactionScope对象的其他一些属性,比如超时时限、隔离级别等采用通过服务行为指定的值。结合前面对System.Transactions事务的介绍,该过程的本质就是创建流入事务的依赖事务,并将创建的依赖事务作为当前的环境事务;
  • 如果入栈消息不存在事务属性,则创建一个新的TransactionScope对象。也就是相当于创建一个可提交事务,并将其作为但前的环境事务。

上面的过程是在操作方法被调用之前完成的,并且和操作方法处于相同的线程中。环境事务的存在确保操作方法的执行被纳入到流入的事务或者是一个全新的事务之中。至于事务参与者之间的协调问题,已经不属于WCF体系管辖的范围了,DTC会接收余下的工作。

如果我们将上面的实现通过代码的形式写出来,相信读者的理解会更加深刻。我们以上面演示的转帐操作的实现为例,下面是响应的代码。由于Transfer方法上通过OperationBehaviorAttribute特性将TransactionScopeRequired属性设成True,WCF服务端运行时会自动为我们实现事务登记。

   1: [OperationBehavior(TransactionScopeRequired = true)]
   2: public void Transfer(string fromAccountId, string toAccountId, double amount)
   3: {
   4: //转帐操作
   5: }

现在我们将OperationBehaviorAttribute特性从Transfer方法中拿掉,通过自己的方式实现事务的自动登记。如果不考虑超时时限和隔离级别等问题,整个实现会如下面的代码所示:

   1: public void Transfer(string accountFrom, string accountTo, double amount)
   2: {
   3:     TransactionScope transactionScope = null;
   4:     if (OperationContext.Current.IncomingMessageProperties.ContainsKey("TransactionMessageProperty"))
   5:     {
   6:         TransactionMessageProperty transactionMessageProperty = (TransactionMessageProperty)OperationContext.Current.IncomingMessageProperties["TransactionMessageProperty"];
   7:         transactionScope = new TransactionScope(transactionMessageProperty.Transaction);
   8:     }
   9:     else
  10:     {
  11:         transactionScope = new TransactionScope();
  12:     }
  13:     try
  14:     {
  15:         //转帐操作
  16:         transactionScope.Complete();
  17:     }
  18:     finally
  19:     {
  20:         transactionScope.Dispose();
  21:     }
  22: }

 

二、OleTx提升(OleTx Upgrade)机制

在《一步步创建一个完整的分布式事务应用》的实例演示中我们谈到,即使我们将绑定采用的事务处理协议设置成WS-AT,并且在DTC中对WS-AT进行了正确的设置,WCF运行时仍有可能采用OleTx协议进行事务处理,这就是将要介绍的OleTx提升机制。

OleTx是Windows平台下默认的分布式事务协议,它采用安全RPC(Secure RPC: SRPC)协议进行通信,并采用二进制编码,具有最好的性能优势。对于WCF事务来说,即使我们显式地将WS-AT设置成绑定采用的事务协议,如果DTC发现当前的事务应用场景仍然能够采用OleTx进行处理,会自动将WS-AT协议提升到OleTx协议,这就是OleTx提升机制。

我们将我们的视线再次移向上面基于TransactionFormatter的例子,通过分析包含有格式化事务数据的三种基于不同事务协议的SOAP消息的结构,我们会发现基于OleTx的所有信息均包含在基于WS-AT的消息之中。实际上,OleTx需要的仅仅是事务的传播令牌(Propagation Token)。也就是说,对于WS-AT协调上下文接收方的DTC是可以通过OleTx进行事务处理的。

在默认的情况下,OleTx提升机制自动生效。我们可以通过修改相应的注册表项对OleTx提升进行开启和关闭,该注册表项就是我们上面提到的HKLM\SOFTWARE\Microsoft\WSAT\3.0\OleTxUpgradeEnabled。接下来我们将介绍在不同的应用场景下将绑定的事务类型设置成WS-AT,分布式事务的实现真正采用的实现方式:

  • 场景1:WCF客户端和服务端不部属于同一台主机,不论是OleTxUpgradeEnabled作何设置,客户端和服务端均采用SRPC与DTC进行通信。实际上,无论对于何种场景,事务参与者与本地DTC之间通信的方式总是SRPC。
  • 场景2: WCF客户端和服务端部属于不同的主机,在没有设置OleTxUpgradeEnabled或者OleTxUpgradeEnabled=1的境况下,DTC之间采用OleTx进行事务处理,通信方式为SRPC。
  • 场景3: WCF客户端和服务端部属于不同的主机,将OleTxUpgradeEnabled设置为0的境况下,DTC之间采用WS-AT进行事务处理;
  • 场景4:WCF客户端调用另一平台服务,DTC和服务所在主机的事务管理器(TM:Transaction Manager)采用WS-AT进行事务处理;其他平台客户端调用WCF服务,DTC和TM之间也采用WS-AT进行事务处理。

上述的4个场景如下图所示:

image


作者:蒋金楠
微信公众账号:大内老A
微博: www.weibo.com/artech
如果你想及时得到个人撰写文章以及著作的消息推送,或者想看看个人推荐的技术资料,可以扫描左边二维码(或者长按识别二维码)关注个人公众号(原来公众帐号 蒋金楠的自媒体将会停用)。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
相关文章
|
C++
WCF框架-分布式联调
WCF框架-分布式联调
101 0
|
Oracle 关系型数据库 API
C# LIS检验系统源码,接口技术:RESTful API + Http+WCF
LIS检验系统一种专门用于医院化验室的计算机系统,它致力于提高医院化验室的工作效率和检测准确率。LIS系统由多个子系统组成,包括样本管理系统、质控系统、检验结果管理系统、报告管理系统等。体系结构:Client/Server架构 SaaS模式 客户端:WPF+Windows Forms 服务端:C# +.Net 数据库:Oracle 接口技术:RESTful API + Http+WCF
114 2
|
网络协议 网络架构 Windows
框架学习——WCF框架
框架学习——WCF框架
293 0
|
API 数据库
如何使用WCF框架和EF框架实现对数据库的操作
如何使用WCF框架和EF框架实现对数据库的操作
|
数据库 C# 数据安全/隐私保护
使用分布式框架WCF出现的BUG记录
使用分布式框架WCF出现的BUG记录
|
C#
C#面向服务编程技术WCF从入门到实战演练
一、WCF课程介绍 1.1、Web Service会被WCF取代吗? 对于这个问题阿笨的回答是:两者在功能特性上却是有新旧之分,但是对于特定的系统,适合自己的就是最好的。不能哪一个技术框架和行业标准作比较,任何对于二者的比较都是错误的,因为两者根不不在同一个范畴里。
1400 0
|
安全 C#
WCF技术我们应该如何以正确的方式去学习掌握
一、WCF技术我该如何学习?       阿笨的回答是:作为初学者的我们,那么请跟着阿笨一起玩WCF吧,阿笨将带领大家如何以正确的姿势去掌握WCF技术。由于WCF技术知识点太多了,就纯基础概念性知识都可以单独出一本书来讲解,本次分享课程《C#面向服务编程技术WCF从入门到实战演练》开课之前,阿笨还是希望从没了解过WCF技术的童鞋们提前先了解一下WCF技术,至少要明白WCF技术的ABC三要素分别指的是什么。
1195 0
|
XML 监控 安全
Adhesive框架系列文章--WCF 分布式服务模块使用和实现
Adhesive框架中的WCF分布式服务模块基于原来写的WCF扩展修改而来,主要的修改如下: 1)原先使用数据库的元数据配置,现在统一改为配置服务,主要是为了统一,不用再去开发一个WCF的配置后台 2)原先直接存储到Mongodb中的各种日志,现在统一使用Monodb数据服务,也是进行了一个统一 3)和信息中心模块中的网站请求状态(统计每一个请求的情况)一样,这里也提供了WCF客户端和服务端的执行状态   这个模块主要实现如下功能: 1)集中化的配置:地址、绑定、契约、端点等等信息都无需在配置文件中配置,直接在统一的配置服务中进行配置。
968 0
下一篇
无影云桌面