谈谈分布式事务之四: 两种事务处理协议OleTx与WS-AT

在年前写一个几篇关于分布式事务的文章,实际上这些都是为了系统介绍WCF事务处理体系而提供的相关的背景和基础知识。今天发最后一篇,介绍分布式事务采用的两种协议,即OleTx和WS-AT,内容比较枯燥,但对于后续对WCF事务处理框架进行深入剖析的系列文章来说,确是不可以缺少的。总的来说,基于WCF的分布式事务采用的是两阶段提交(2PC:Two Phase Commit)协议。具体来说,我们可以选择如下两种事务处理协议实现WCF的分布式式事务,它们按照各自的方式提供了对两阶段提交的实现。

  • OleTx:OleTx采用RPC作为通信的手段,通信消息采用二进制编码方式,所以OleTx是最为高效的分布式处理协议。但是也正是由于OleTx自身的通信和编码方式,使它成为了专用于Windows平台下的分布式处理协议。也就是说,当一个分布式事务的所有参与者均基于Windows平台,OleTx是最好的选择,如果有任何一个非Windows的事务资源参与进来,OleTx就无能为力了。说白了,OleTx并不具有跨平台的特质;
  • WS-AT:WS-AT(WS-Atomic Transaction)是WS-*大家庭中的一员,是由结构化信息标准促进组织(OASIS:Organization for the Advancement of Structured Information Standards)制定的基于分布式事务的标准。对于WCF来说,WS-AT弥补了OleTx不具备跨平台的不足。

限于篇幅的问题,本书不会对OleTx具体的实现进行介绍,有兴趣的读者可以从MSDN网站下载OleTx事务管理的规范文档,地址为http://msdn.microsoft.com/en-us/library/cc229116%28PROT.10%29.aspx。接下来,我们来讨论WS-AT是以怎样的方式来对分布式事务的管理的。实际上,WS-AT建立在另一个WS规范之上,即我们将要介绍的WS-Coordination。

一、 WS-Coordination

以SOAP和WSDL为核心的Web服务规范定义了一套完善的协议以实现Web服务的互操作,使我们可以将若干的参与者组合起来构成一个分布式的计算单元(Distributed Computational Unit),我们将这些计算单元称为分布式活动(Distributed Activity)。这些活动可能在结构上非常复杂,各个参与者之间具有复杂的关系;也可能由于业务流程的复杂性或者需要用户交互,需要很长的执行时间。分布式事务和工作流就是两个典型的分布式活动。

由于组成这个分布式计算单元或者活动的参与者隶属于不同的厂商,有效地协调这些参与者必须依赖于一个开放的、大家均遵守的标准或者规范,我们本节介绍的WS-Coordination就是这样一个规范。WS-Coordination有一个称为“结构化信息标准促进组织(OASIS:Organization for the Advancement of Structured Information Standards)”的标准制定,到目前为止先后推出了两个版本:V1.1和V1.2,本节我们讨论的是WS-Coordination 1.1。

WS-Coordination通过一个协调器(Coordinator)和若干协调协议(coordination protocol)定义了一个扩展的框架去协调组成一个分布式活动的所有参与者。这样一个框架使这些参与者达成一种一致性的协定,合力完成这个依赖于所有参与者的活动。WS-Coordination为分布式活动协调定义了一个统一的、抽象的处理协议,其本身并不用于解决具体的协调问题。基于WS-Coordination定义的标准,一系列的具体标准会被陆续制定出来意解决具体的分布式活动的协调问题。WS-AT(WS-AtomicTransaction)和WS-BA(WS-BusinessActivity)就是两个基于WS-Coordination的协调协议。接下来,我们就按照逐层深入的方式介绍基于WS-Coordination的分布式活动协调机制。

1、基于协调器(Coordinator)的协调模型

WS-Coordination的协调模型以协调器(Coordinator)为中心,协调器由一系列进行协调操作的服务构成。分布式活动的参与者调用本地协调器相应的服务,各个分布的协调器相互通信从而构建了一个统一的协调环境,并将所有的参与者纳入其中。

图1 基于协调器(Coordinator)的协调模型

我们说一个协调器可以看成是一个协调服务的容器,包含在该容器中的所有服务按照其不同的作用可以分成如下三个类型,不同服务在协调器中的构成如图2所示。

  • 激活服务(Activation Service):当一个分布式活动开始的时候,初始化该活动的参与者调用激活服务的CreateCoordinationContext创建协调上下文(Coordination Context);
  • 注册服务(Registration Service):的参与者通过调用注册服务的Register方法参与到相应的协调协议之中;
  • 协议服务(Protocol Service):一个协调器会有一系列基于具体协调协议(比如WS-AT和WS-BA等)的服务。

图2 协调器的服务构成

接下来我们详细介绍基于WS-Coordination协议如何实现将分布式活动在不同的参与者之间进行传播,整个过程如图3所示。整个活动具有两个参与者:Application 1和Application 2,它们具有各自的协调器Coordinator1和Cooridiatior2,AS和RS分别表示协调器的激活服务和注册服务。假设协调整个活动的具体的协调服务为Q(你可以假设这就是我们接下来要介绍的WS-AT),而PS1和PS2分别表示给予该协调类型的协议服务。由于PS1和PS2最终实现了对整个活动的协调管理,所以整个流程的目的在于如何让PS1和PS2能够互相通信。说得更加具体一点,按照WS-Addressing规范,服务通过终结点引用(Endpoint Reference)来定位,整个流程的目的在于交换PS1和PS2的终结点引用,使之能够彼此调用。

步骤1:活动的初始化者Application1调用本地的协调器Coordinator1的激活服务AS1创建协调上下文。我们称该上下文为Context1,Context1包含了如下信息:活动标识、协调器Coordinator1的注册服务RS1的终结点引用和协调类型Q。

步骤2:Application1将创建的协调上下文Context1发送到另一个活动参与者Application2。

步骤3: Application2以此协调上下文Context1作为输入,调用本地协调器Coordinator2,并创建新的协调上下文Context2。Context1和Context2具有相同的活动标识和协调类型,但是注册服务终结点指向本协调器的注册服务RS2。

步骤4:Application2根据接收到的协调上下文中的协调类型信息Q确定具体的协调协议,调用注册服务RS2将PS2注册到Coordinator上。注册的结果是Application2和PS2进行了终结点引用交换,从而建立起两者之间的逻辑关系。

步骤5: RS2根据接收到的协调上下文Context1得到RS1的终结点引用,将PS2的终结点引用作为输入调用RS1注册到Coordinator1上,RS1将PS1的终结点引用返回。到此为止,PS1和PS2实现了相互之间的终结点引用的交换。

图3  基于WS-Coordination协议对一个分布式活动进行协调的全过程

2、从消息交换看激活服务和注册服务

从上面的步骤我们不难看出,整个处理流程主要涉及到对协调器两个服务的调用,即激活服和注册服务。接下来,我们从消息交换的角度对这两个服务的调用进行进一步的介绍。在这之前我们先来看看介绍一下上面我们频繁体积的协调上下文(Coordination Context)。

协调上下文(Coordination Context)

当一个分布式活动需要从一个参与者传播到另一个参与者,相应的协调上下文文需要传播到目标参与者,换句话说,协调上下文的传播是分布式活动传播的手段。协调上下文的传播通过应用定义的机制实现,比如将协调上下文至于SOAP消息相应的报头中。协调上下文包括活动标识、协调的具体类型、注册服务的终结点地址以及其他一些扩展信息。顺便提一下,http://docs.oasis-open.org/ws-tx/wscoor/2006/06是WS-Coordination 1.1对应的命名空间。

激活服务(Activation Service)

激活服务的目的就是创建协调上下文,所以它只有一个唯一的操作CreateCoordinationContext。当活动初始化参与者需要创建协调上下文时候,向激活服务发送相应请求,指定具体的协调类型已经以及其他相关信息。下面的XML片断表示了一个CreateCoordinationContext请求消息的结构:

   1: <CreateCoordinationContext ...="">
   2:   <Expires> ... </Expires>?
   3:   <CurrentContext> ... </CurrentContext>?
   4:   <CoordinationType> ... </CoordinationType>
   5:   ...
   6: </CreateCoordinationContext>

其中只有<CoordinationType/>结点是必须的,表示具体的协调类型,比如WS-AT(http://docs.oasis-open.org/ws-tx/wsat/2006/06),其他均为可选元素。<Expires/>结点的值是一个以正数表示的过期时限,单位是毫秒,自该上下文被接收的那一刻算起。<CurrentContext>结点表示的是当前的协调上下文,如果为空则创建一个全新的上下文,否则创建一个与之关联的上下文(具有相同的活动标识)。通过指定当前上下文,让创建的上下文和当前上下来建立起一种上下级的依赖关系。此外,CreateCoordinationContext请求消息还可以根据具体协调类型的需要添加任意扩展的元素。

当激活服务接收到CreateCoordinationContext后,根据请求的内容创建相应的协调上下文,并将其置于CreateCoordinationContextResponse消息中返回。CreateCoordinationContextResponse消息的主体结构如下面的XML片断所示。其中CoordinationContext就是创建出来的协调上下文。

   1: <CoordinationContext> ... </CoordinationContext>
   2:   ...
   3: </CreateCoordinationContextResponse>
注册服务(Registration Service)

当分布式活动的参与者从本地协调器获取了协调上下文,就可以调用相应的注册服务将具体的协调服务注册到该上下文对应的活动中。此外,位于活动参与者与上级协调器之前的中介协调器(图3中的Coordinator2)通过调用上级协调器的注册服务进行相类似的注册操作。

注册服务具有一个唯一的Register操作,注册者(活动参与者或者下级协调器)发送相应的Register请求,并指定具体协调协议的标识和参与方协调服务的终结点引用。Register请求消息主体部分结构如下。

   1: <Register ...="">
   2:   <ProtocolIdentifier> ... </ProtocolIdentifier>
   3:   <ParticipantProtocolService> ... </ParticipantProtocolService>
   4:   ...
   5: </Register>

下面是WS-AT基于Volatile2PC(WS-AT定义了两个2PC协议:Volatile2PC和Durable2PC)协议的Register请求消息,其中参与方Volatile2PC服务终结点引用的地址为http://Adventure456.com/participant2PCservice

   1: <Register>
   2:   <ProtocolIdentifier>
   3:     http://docs.oasis-open.org/ws-tx/wsat/2006/06/Volatile2PC
   4:   </ProtocolIdentifier>
   5:   <ParticipantProtocolService>
   6:     <wsa:Address>
   7:       http://Adventure456.com/participant2PCservice
   8:     </wsa:Address>
   9:     <wsa:ReferenceParameters>
  10:       <BetaMark> AlphaBetaGamma </BetaMark>
  11:     </wsa:ReferenceParameters>
  12:   </ParticipantProtocolService>
  13: </Register>

当注册服务接收到Register请求后,会返回相应的RegisterResponse消息,该消息中包含己方相应的协调服务的终结点引用。RegisterResponse消息主体部分结构如下:

   1: <RegisterResponse ...="">
   2:   <CoordinatorProtocolService> ... </CoordinatorProtocolService>
   3:   ...
   4: </RegisterResponse>

二、WS-AT

WS-Coordination为处理不同类型的协调定义了一个统一的、可扩展的框架,而原子事务(AT:Atomic Transaction)是众多协调类型中最为典型的一种。原子事务协调的对象是那些运行生命周期相对短暂的活动(Short Lived Activity),是之保持“要么全做,要么都不做(All or Nothing)”的属性。WS-AT(WS-Atomic Transaction)在WS-Coordination的基础上,为原子事务这样一种协调类型定义了若干协议,使隶属于不同平台或者厂商的事务处理系统可以进行互操作。

WS-AT规范的制订者也是结构化信息标准促进组织(OASIS),目前的版本有两个:WS-AT 1.0和WS-AT1.1,我们主要介绍后者。由于WS-AT建立在WS-Coordination之上,完全按照WS-Coordination规定的方式进行协调上下文的创建和服务注册,我们先来简单介绍一下基于WS-AT的协调上下文。

1、WS-AT协调上下文(Coordination Context)

当一个分布式事务的参与者需要将当前事务传播给另外一个事务参与者的时候,需要调用本地协调器的激活服务创建基于原子事务协调类型的协调上下文,并将上下文通过消息交换的方式进行传播。如果采用SOAP消息,需要按照SOAP绑定将上下文作为SOAP报头进行传输。下面的XML展现的一个简单的原子事务协调上下文的结构。

   1: <CoordinationContext>
   2:   <Expires>100000</Expires>
   3:   <Identifier>urn:uuid:f0660731-4eb8-4ed2-a7bd-1b3a68d2443a</Identifier>                  <CoordinationType>http://docs.oasis-open.org/ws-tx/wsat/2006/06</CoordinationType>
   4:   <RegistrationService>
   5:     <wsa:Address>
   6:       http://Business456.com/tm/registration
   7:     </wsa:Address>
   8:     <wsa:ReferenceParameters>
   9:       <myapp:PrivateInstance>1234</myapp:PrivateInstance>
  10:     </wsa:ReferenceParameters>
  11:   </RegistrationService>
  12: </CoordinationContext>

其中表示协调类型的<CoordinationType>的值为http://docs.oasis-open.org/ws-tx/wsat/2006/06,代表基于WS-AT 1.1的原子事务协调类型。这个URI也这正是WS-AT 1.1的命名空间。<Expires>结点代表上下文过期的时限,单位是毫秒,自上下文被创建或者被接收的那一刻算起,这实际上也就是分布式事务超时时限。<RegistrationService>是创建该上下文协调器注册服务的终结点引用。

在介绍WS-Coordination的时候,我们谈到协调上下文通过调用协调器激活服务的CreateCoordinationContext操作获得。在CreateCoordinationContext请求中,我们是可以制定一个现有的协调上下文的,在这种情况下,注册服务会创建与该上下文相关联的上下文,这种关联即它们具有相同的上下文标识。反映在具体事务场景中,就是这样:事物初始化者调用原子事务协调器的激活服务创建一个全新的上下文,而事务后续参与者在创建上下文时候,会将接收到的上下文作为输入,调用本地的协调器创建与之管理的上下文。两个原子事务协调器建立起一个上下级的关系,两个上下文具有的相同的标识即事务的分布式ID。

2、 原子事务协议

WS-AT为原子事务处理定义了如下的协议:Completion和两阶段提交(2PC)。

完成(Completion)

分布式事务的初始化应用使用Completion协议通知协调器提交或者中止开启的原子事务。当事务结束后,最终的状态(被中止或者被提交)返回到该应用。Completion协议的协调器必须是原子事务的根协调器。对于非根协调器的注册请求,注册服务将会返回“Cannot Register Participant”WS-Coordination错误(Fault)。注册Completion协议采用的协议标识为:http://docs.oasis-open.org/ws-tx/wsat/2006/06/Completion

两阶段提交(2PC)

该协议通过协调原子事务的所有参与者,并对整个事务作出最终的决定(提交或者中止),并确保最终的结果抵达所有的参与者。根据事务参与者的不同,两阶段提交协议具有两个变体:

限于篇幅的问题,我们不能够对WS-AT的三种协议进行深入的讨论,有兴趣的读者可以从OASIS的网站上直接下载WS-AT的官方文档。后续博文中我将来介绍WCF基于事务的编程问题,敬请期待!

分布式事务系列: 谈谈分布式事务之一:SOA需要怎样的事务控制方式 谈谈分布式事务之二:基于DTC的分布式事务管理模型[上篇] 谈谈分布式事务之二:基于DTC的分布式事务管理模型[下篇] 谈谈分布式事务之三: System.Transactions事务详解[上篇] 谈谈分布式事务之三: System.Transactions事务详解[下篇] 谈谈分布式事务之四: 两种事务处理协议OleTx与WS-AT

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏带你撸出一手好代码

神奇的Java

使用java开发一个socket服务器,使用protocol buffer作为和客户端通信的数据格式。然后,问题就来了,这个socket服务器要如何调试?换句话...

1002
来自专栏腾讯移动品质中心TMQ的专栏

流量都去哪儿了 —— 三板斧搞定Android网络流量测试

流量是什么? 为什么要进行流量测试? 流量测试方法有哪些? 怎么统计流量并进行结果分析? 带着这些疑问,小编带您探寻Android网络流量的测试方法。 1 ...

4346
来自专栏Java技术分享

java系统高并发的解决方案

一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要求...

7498
来自专栏Java技术分享

java系统高并发的解决方案

一个小型的网站,比如个人网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构、性能的要...

7889
来自专栏铭毅天下

Elasticsearch大文件检索性能提升20倍实践(干货)

少废话,直接开始。 1、大文件是多大? ES建立索引完成全文检索的前提是将待检索的信息导入Elaticsearch。 项目中,有时候需要将一些扫描件、PDF文档...

3896
来自专栏电光石火

idea 创建的maven+spring+mybatis项目整合 报错无法创建bean

最近在做一个由maven构建的spring+spring mvc+mybatis项目,刚开始的时候是用自己的电脑Win10环境下的eclipse写的,托管到了码...

1938
来自专栏CDA数据分析师

案例分析:基于消息的分布式架构

美国计算机科学家,LaTex的作者Leslie Lamport说:“分布式系统就是这样一个系统,系统中一个你甚至都不知道的计算机出了故障,却可能导致你自己的计算...

2798
来自专栏腾讯Bugly的专栏

《手Q Android线程死锁监控与自动化分析实践》

手Q每个版本上线以后研发同学都会收到各种问题反馈。在跟进手Q内部用户反馈的问题时,发现多例问题,其表象和原因如下:

9098
来自专栏C/C++基础

C/C++代码调试的几点建议

代码调试在程序开发阶段占有举足轻重的地位,可见代码调试的重要性。但是有一点必须强调:程序是设计出来的,而不是调试出来的。这是所有程序员必须牢记在心的一条准则。一...

831
来自专栏求索之路

从零开始仿写一个抖音App——日志和埋点以及后端初步架构本项目的 github 地址:MyTikTok

拿 Java 来说:比如我们有两个服务 A、B 在两个服务器上,此时我们要在 A 上调用 B 的服务获取其上的数据 Foo。那么在 A 中可以写成 Foo f ...

4605

扫码关注云+社区

领取腾讯云代金券