阿里、蚂蚁、晟腾、中科加禾精彩分享 AI 基础设施洞见,现购票可享受 9 折优惠 |AICon 了解详情
写点什么

扩展事务简史

  • 2007-03-26
  • 本文字数:12122 字

    阅读完需:约 40 分钟

业务流程管理的扩展事务处理模型:从 CORBA 到 Web 服务

摘要

原子事务处理是在出现故障的情况下,保证一致性的一种广为人知的技术。原子事务处理的 ACID 属性,可以确保在即便是复杂的业务应用中,不管是否出现并发存取和故障,状态的一致性得以保持。然而,尽管这是一个极其有用的容错技术,但是它对于长时间跨度的事务来说,并不足以满足需要。因为长时间跨度的事务中,对事务属性的放宽是必要的。所谓的扩展事务处理模型已经出现好多年了,但是直到 Web 服务问世以前,它们仍然趋于停留在学术研究的环境中。在这篇文章中,我们将考察这些需求,并且检验在 CORBA 的紧耦合环境下开发出的扩展事务处理的业界标准,如何极大地影响了 Web 服务的松耦合环境。

引言

分布式系统使原先在集中型系统下不常见的可靠性问题突显出来。分布式系统由大量用网络连接起来的计算机所组成,常常会遭受其中的任意子部件出现的故障,比如计算机本身、网络连接、操作系统、或者个别的应用程序,以及一些执行时间不能确定的行为活动等。去中心化允许整个系统的某个部分出现故障,而其他部分保持运行。但这样会导致执行程序过程中出现异常行为的可能。在 Web 服务出现以后,想利用这个巨大的 B2B 空间的服务供应商一拥而上。然而,Web 是有史以来最大的分布式系统,并且会有故障发生,这些故障会影响在 Web 上运行的应用程序的性能和一致性。

原子事务处理是在出现故障的情况下,保证一致性的一种广为人知的技术 [1]。它的 ACID 属性,可以确保在即便是复杂的业务应用中,不管是否出现并发存取和故障,状态的一致性都得以保持。这是一个极其有用的容错技术,尤其在牵扯到多个资源(可能是远程资源)的情况下。

然而,由于 Web 服务已经发展成为在跨企业级别集成进程和应用程序的一种方式,传统的事务处理的语义和协议已被证明不合时宜。基于 Web 服务的事务与传统事务的不同之处,在于前者的执行周期长,要求事务的提交必须在运行期“协商”,并且隔离级别必须被放宽。所谓的扩展事务处理模型已经出现好多年了,但是直到 Web 服务问世以前,它们仍然趋于停留在学术研究的环境中。然而,OASIS Web 服务事务(WS-TX)技术委员会正在制定用于 Web 服务事务管理的标准 [2],这个标准就采用了扩展事务处理模型。在这篇文章中,我们将首先考虑为什么传统的原子事务处理不足以满足长周期活动的需要,其次,我们将以 Web 服务出现之前在 OMG 进行的研究和开发工作为基础,详述 WS-TX 如何解决这些问题。

为什么需要扩展事务处理模型?

许多年以来,分布式对象加上 ACID 事务为创建高完整性的业务应用程序构建了基础。事务的 ACID 属性,确保即便在复杂的业务应用程序中,不管是否出现并发存取和故障,应用程序的状态一致性都能得以保持。事务可以由两种方式终止:被提交或者被中止(回滚)。当一个事务被提交时,在其过程中的所有改变将被持久化(被保存在稳定的存储设备上,比如磁盘)。当一个事务被中止时,在事务生命周期中所作的修改都会被撤销。

传统的事务系统使用一种两阶段协议来确保参与者之间的原子性的实现,如图 1 :在第一(准备)阶段中,单独的参与者必须使事务的作用域中每一个状态的改变持久化,以便在事务结果一旦得以确定,所作的改变就能被回滚或提交。假定第一阶段没有出现任何故障,则参与者可以在第二(提交)阶段使用在第一阶段持久化的状态“覆盖”原来的状态。

图 1:两阶段提交协议为了保证一致性,两阶段提交必须是一个阻塞型的协议:在第一阶段的响应返回之后,每一个返回了提交响应的参与者必须保持阻塞状态,直到收到协调程序发出的第二阶段消息。在它们收到消息之前,所有被该参与者使用的资源都无法为其他事务所用,否则会导致非 ACID 行为的产生。如果协调程序在第二阶段消息被发送之前发生故障,这些资源都将保持阻塞状态,直到协调程序完成恢复。

多数人意见组(Consensus groups)

人们很早就意识到,ACID 事务本身并不足以用来构造长时间运行的应用程序[3][4]。其中一项著名的改进(由 CORBA 对象事务服务 OTS 所支持[5]),就是允许事务的嵌套;此外,嵌套的事务可以是并发的。在这个层次结构中,最外层的事务一般被称为顶级事务。持久性属性只能由顶级事务所拥有,而嵌套事务(子事务)的提交相对于外层事务的提交或者中止来说,是临时的。这样,就考虑到了故障制约策略的具体情况,也就是说,子事务的错误不会一定引起它的外层事务出现错误。在子事务中取得的资源,会在它被提交的时候,被其父事务所继承(保留),而且只在顶级事务完成时才能被释放(假设没有故障发生)。换句话说,这些资源会被保持到顶级事务结束为止。

上述的改进,在应用程序功能可以被表示为单独的顶级事务的时候是可以满足需求的。但事实上常常并不是这么一回事。顶级事务最适合被视为“短寿命”实体,对系统进行稳定的状态变更[4];它们比较不适合用于构造“长寿命”的应用程序功能(例如运行数个小时乃至数天)。长跨度的顶级事务可能会因为长时间占用某些资源,而使系统的并发性降低到令人无法接受的程度;此外,如果这样一个事务中止的话,许多之前完成的有价值的工作可以被撤销。简而言之,如果应用程序由一系列的事务所组成,那么在运行期间,代表运行中的应用程序的整个活动,会被频繁地要求放宽对于各个事务的其中一些 ACID 属性的要求。于是,整个活动可以被看成一个非 ACID 的“扩展事务处理”。

控制模型的范围[6] 描述了扩展事务处理中的恢复和提交等根本概念。在开发具体的扩展事务处理模型方面,人们已经进行了许多的研究[例如 7 - 10],集中在多数人意见组的意见上。并非在某个特订的扩展事务处理中的所有参与者都必须得到相同的结果;一个特定的事务可能会拥有多个不同的多数人意见组,其中每个组中的参与者得到不同的结果。另外,在某一些多数人意见组中可能允许放宽某个特定事务的原子性的限制,从而允许参与者的子集得到不同的结果。这种在一个组中的参与者列表的灵活性,是这些类型的扩展事务处理和传统的事务系统的一个重要区别。

进而言之,假如需要的话,参与者应当可以退出一个多数人意见组。参与者可能不再希望参与多数人意见组的理由会有很多:例如,它所完成的工作可以安全结束,而不必考虑多数人意见组的最终结果;或者,在多数人意见组取消工作的时候,另外一个独立任务(不同的服务或者领域)可能有必要执行反效果。

多数人意见组在参与者当中取得了一致性结果,但他们仅仅是冰山一角。在业务对业务(business-to-business)关系中,常常存在着这些组的层次关系(工作的范围),在这些层次关系之间包含着父子关系。总的来说,在业务事务处理内部确认或者取消已经完成的工作,将意味着由参与者来进行决策。譬如,应用程序可能选择执行变更,作为临时效果,并且使它们对其他业务事务处理可见。同时,应用程序可能储存必要的临时信息,用于撤销这些变更。在确认时,它只要把这些撤销信息丢弃就可以了;或者,在取消时,它可以应用这些撤销的改变。例如,应用程序可以采取类似这样基于补偿的方案,也可以采用传统的“回滚”方法。

除了理解这些结果以外,业务事务处理内部的参与者可能需要在事务处理的过程中支持临时或者尝试性的状态变更。这些参与方(parties)也必须通过确认(最终效果)或者取消(反效果)来支持业务事务处理的完成。总的来说,在业务事务处理内部确认或者取消已经完成的工作,将意味着由参与者来进行决策。譬如,应用程序可能选择执行变更,作为临时效果,并且使它们对其他业务事务处理可见。同时,应用程序可能储存必要的临时信息,用于撤销这些变更。在确认时,它只要把这些撤销信息丢弃就可以了;或者,在取消时,它可以应用这些撤销的改变。例如,应用程序可以采取类似这样基于补偿的方案,也可以采用传统的“回滚”方法。

CORBA 活动服务

尽管实际上对于扩展事务处理存在着明显的需求,上述提议的技术中的大部分还没有得到广泛使用;事实上,大多数业务事务处理系统甚至不提供对事务嵌套的支持。理由之一就是缺乏灵活性 [11],扩展事务模型的大规模应用显示单一模型对所以应用来说还不够,所以要硬绑定一个特定的扩展机制是不合适的。在任何情况下,多数事务处理监视者(transaction processing monitors)在结构上都是自成整体的,对它们进行扩展,难度非常大。因此,这种情况一直保留,以至于程序员常常必须开发针对应用程序的机制,来构建扩展事务处理。

这种情况的解决方法之一,就是采用基于中间件的方法;以 CORBA 为例,已经存在一系列开放服务可以用于构建分布式应用程序。上下文里,在允许应用程序持有某些或者全部 ACID 属性的支持下,对使用事务处理组装应用程序的灵活方法检查需要哪些额外的功能,是比较合适的。这是 CORBA 活动服务的工作基础 [12],它洞察到不同的扩展事务模型可被通过提供一个普遍的目的事件信号机制来支持,这个机制能被编程以驱动活动——计算的应用特定单元——从而将每个单元以一种仍在考虑中的扩展事务模型所描述的方式接合起来。

不同的扩展服务模型可以被映射到具体活动服务框架的实现上。此框架允许事务跨越由某种分布式结构间接连接起来的系统的网络。

因而,CORBA 活动服务标准定义了两个实体 [13]:

  • 协调程序:这是一个一般的协调程序,仅负责发送和接收任意类型的消息(称为信号)。这样做的目的,是使协调程序的实现仅仅是一个框架,仅当扩充时有用。
  • 协调程序智能:这是对协调程序的扩充(成为信号集),用来允许协调程序执行某个具体的协议,比如两阶段提交。这是活动服务扩展性的关键。

一个给定的协调程序实现,可以接受任意数量的信号集,用来执行不同的协议。这样的结果就是,协调程序是一个相当轻量级的实体,把它的多数职责委任给了信号集。

尽管最初这个框架被设计成了 CORBA 的一个部分,但是它的主要思想具备了足够的普遍性,所以后来它被 J2EE 体系结构所采用,作为它的一部分 [14]。当人们在 2001 年第一次尝试为 Web 服务定义工业标准的时候 [15],其中一个最初提交稿就是基于活动服务的 [16];不巧的是,这个提议并没有被接受,直到 2006 年另外一个类似的提议才以 OASIS WS-TX 委员会的形式重新崭露头角。

Web 服务协作

虽然,最初的 CORBA 活动服务被计划作为扩展事务处理的框架,但很明显,它可以得到更广泛的应用:在所有需要协作的地方。在分布式应用程序的许多不同的方面,协作是一个必要条件,例如工作流、安全、原子事务处理、缓存与复制、拍卖以及 B2B 活动等。所幸的是,Web 服务体系结构现在尚不成熟,并且在不断发展,所以将协作作为基础服务颇为合适。

因此,不同于原来的 OMG 活动服务,定义 Web 服务事务处理标准的最初提议,就是把协作的方面单独分离出来,以便它能被更广泛地应用。这就是 Web 服务协作规范(WS-Coordination 规范)的目标 [2]:为协作提供一个轻量级框架,可以被扩充以符合特定的需求。如图 2 所示:

图 2:WS-Coordination 和 Web 服务事务处理。WS-Coordination 规范定义了活动的抽象概念,即工作的分布式单位,包括一个或者多个参与者(可能是服务、组件,甚至可能是对象)。在这个级别,对活动的规定被最小化,活动被简单地创建,运行,然后完成。而扩充 WS-Coordination 和定义活动则成为更高级别的服务或者规范的职责。

不管我们使用哪一种协调协议,都存在同样的需求:

  • 对于一个特定的应用程序实体,实例化(或者激活)一个新的协调程序,用于指定的协作协议;
  • 向协调程序注册参与者,以使得参与者可以在应用程序的(某一部分)生命周期中收到协调程序的协议消息;
  • 在由应用程序组成的 Web 服务之间,进行上下文信息的传播;上下文环境包含了充分的信息,可以唯一区分协调程序实体;
  • 用于驱动协作协议直至完成的实体。

用于 WS-Coordination 的模型,是基于 OMG 活动服务的相似概念:定义一个轻量级的协调程序基础结构。在 WS-Coordination 中,这是通过两个 Web 服务来完成的。

第一个是激活服务,支持为特定协议以及与他们关联的上下文环境创建协调程序。调用激活服务的过程是异步发生的,所以激活服务回调,来传递用于鉴别事务和协调程序地址的类型的上下文环境。这个异步方式降低了端点之间的紧密耦合(这在其他环境中是经常看到的)。这种方式的优势是改善了容错性、模块化和部署考虑事项。

一旦通过激活服务实例化了协调程序,并创建了相应的上下文环境,第二种类型的服务——注册服务——就被创建并且公开。注册服务允许被注册的参与者接收和特定协调程序相关的协议消息。与激活服务类似,注册服务也采用异步的通信方式。

除了一般的协调程序的特定错误,WS-Coordination 规范中其他没有定义什么,将协议的细节留给了用户,例如各种各样的 Web 服务事务处理规范。

Web 服务事务处理

目前 WS-TX 委员会定义了两种事务模型,用于扩充 WS-Coordination。在这一节,我们会对这两个模型进行比较和对照。值得注意的是,这两种模型并不打算去涵盖所有可能的事务用例。如果出现无法使用现存事务协议解决的场景,则应当定义另外的模型(以及相关协议),来进一步扩充 WS-Coordination。

原子事务处理协议

原子事务处理(AT)协议就是一个多数人意见组,在这个组中的参与者中强制严格的原子性。已经有很多文章认为原子事务处理对于 Web 服务是不适合的 [17][18]。然而,这些文章都忽视了使用原子事务处理的核心原因:互操作性和短周期交互。传统的事务处理系统在 Web 服务中还是可以占有一席之地的,而这恰恰是原子事务处理打算被应用到的地方。传统事务处理系统间互操作性的实现,是人们很多年来长期努力的目标。在 Web 服务以前,业界里最接近的成果,就是 OMG 开发的对象事务服务。但是即便如此,开发这个服务的可互操作版本也花费了近十年时间。而 Web 服务似乎没用那么长时间就解决了这个问题。[19]

要开始一个原子事务处理,客户端应用程序必须首先定位一个协调服务(WS-Coordination 的实例),这个协调服务支持正确的模型。一旦协调服务定位完成,客户端就会通知它开始一个新的事务,并且取回一个事务上下文环境,这个环境包含了对该事务注册服务的引用。在取得上下文环境以后,客户端应用程序就继续与 Web 服务交互,以完成它的业务级工作。对于业务服务的每次调用,客户端都会传送上下文,这样事务就可以隐式地确定每个调用的范围。

一旦所有必要的应用程序级工作都完成了,客户端就会终止这个事务。事务的中止使用传统的(持久性的)两阶段提交协议(Durable2PC);参与者被期望对持久性数据进行操作,比如数据库中的表格或者文件系统中保存的资源。原子事务处理协议和传统事务系统的一个显著区别,就是缺少一阶段提交的优化 [3]:如果事务包含一个单独的参与者,那么这个参与者的决策就是隐式的事务处理结果,这样就只需要一个单阶段的协议。在 Web 服务事务处理协议中缺少这样的支持是一个无意的疏忽,这个疏忽会反过来影响性能。

图 3 展示了一个原子事务处理的状态转换图,以及协调程序和参与者间的消息交换;用实线表示的是由协调程序产生的消息,而用虚线表示的是参与者消息。

图 3:两阶段提交的状态转换图 除了传统的 Durable2PC 协议,原子事务处理协议还支持 Volatile2PC(短时间两阶段提交),它的准备阶段运行于整个Durable2PC 之前,而其提交或回滚阶段运行于 Durable2PC 完成之后。这个协议背后的原因,是因为访问持久性存储器常常是性能瓶颈。因此,对一个对象的状态(例如整个数据库表格)的缓存和事务周期内对缓存下来的状态进行操作,相较于持续地从数据库往返交互的方式,可以显著地提高性能。然而,在事务处理提交之前很显然需要强制将状态更改为最初的持久化存储。

Volatile2PC 把两阶段提交协议变成了一个四阶段协议:

  1. 在事务处理开始 Durable2PC 之前,所有用 Volatile2PC 注册的参与者都被通知到,并可以清空缓存数据。这时的任何失败都会导致事务处理的回滚。
  2. 然后协调程序执行完整的 Durable2PC 协议。
  3. 一旦事务处理中断,Volatile2PC 协议的第二段就被执行。但是,因为在这儿有些错误被忽视了,所以这是一个礼貌语:事务中断所以没有什么影响。

原子事务处理模型在 Web 服务里成功地模拟出传统的 ACID 事务处理协议。这被意味着可以匹配已存在的事务处理标准,这些标准对原子性(组成良好且双段)、隔离性(无脏读取,重复读取)和持久性(不丢失数据)等有很好的定义行为。

业务活动(Business Activities,BA)

业务活动是为长时间事务处理特别设计的,在这儿要单独锁定资源是不可能也不现实的。在这个模型(基于 Sagas 扩展事务处理模型 [11])里,需要请求服务来处理,而且服务在这儿也可以撤销任何处理工作,服务通知 BA 如果 BA 稍后决定取消,它可以指示服务执行它的撤销动作。

如前所述,业务活动也许会被分成几个范围。这些范围可以被嵌套成任意的层次,组成父子关系。一个父范围具有为一个特定的业务活动,选择在整个输出协议中要包含哪个子任务的能力。因此,非原子输出是可能的:业务活动定义多数人意见组,以允许放宽基于业务层决定的原子性。

一个子任务结束时,他即可以离开业务活动,也可以通知父任务它完成的工作可以稍后补偿。在后面的案例中,补偿任务也许会被父任务调用,因为最后需要撤销子任务完成的处理。

不像原子事务处理协议模型,参与者只在需要时通知协调程序他们的状态,在业务活动里的任务可以直接指定它的输出到父任务,而不需要等待请求。这个特性在任务失败的情况下是有用的,这样业务活动异常处理器(exception handler)就可以使用通知修改目标和驱动处理继续进行,而不用仅仅是等待到事务处理结束后确信它已经失败时才有所行动——一个设计优秀的业务活动应该是能前射的。

综上所述是下面三个基本假设:

  • 所有的状态事务处理被忠实地记录,包括应用状态和协调元数据(收发消息的记录);
  • 所有的请求消息是公认的,所以问题能尽可能早地被检测出来。这就避免了非必要任务的执行,还能在问题较简单和耗费不多时就被发现;
  • 通过原子事务处理,响应被定义成一个单独的操作,而不是请求的输出。消息输入 / 输出实现会特别有对一些业务活动响应来说太短的超时设定。如果响应在一个超时后没有被收到,它会继续重复,直到响应被接收。这个请求接收器除了接受一个同一的请求外,其他的都被丢弃。

通过原子事务处理协议,BA 模型有多个协议:BusinessAgreementWithCoordinatorComplete 和 BusinessAgreementWithParticipantComplete。但是,不像被从协调程序驱动到参与者的 AT 协议,这个协议更多地是从参与者上开始驱动。

在 BusinessAgreementWithParticipantComplete 协议下,子活动开始以一个活动状态被创建,如果它结束了需要创建它来处理的工作,并且在 BA 范围(比如在活动操作常数时)内没有更多的参与者,那么子活动就可以单方面脱离出父范围。但是,如果子任务结束了,并且想在 BA 里继续,那么它必须能补偿它已经执行的工作。在这个例子里,它通知父范围,然后等待着接收从父范围处来的 BA 最终输出。

除了子活动不能自主决定在业务活动中终止它的参与者,BusinessAgreementWithCoordinatorComplete 协议和 BusinessAgreementWithParticipantComplete 协议是一样的,尽管它可以被补偿。在子任务收到所有给它的请求时,它依赖父范围通知它,然后执行父范围通过给子任务发送完全消息通知它的处理。然后子任务开始像它在 BusinessAgreementWithParticipantComplete 协议里做的一样,开始行动。

范例场景

在本节中,我们将观察这样一个范例,其中业务活动比原子事务处理处理更为合适。在这个范例中,我们将取一个相对简单的场景——为会议安排旅行和住宿。特别地,会议出席者需要预订到会议举办地的航班和当地酒店的一个房间,还可能要在会议期间租赁一辆汽车。在查找航班、酒店和租赁汽车的选择时,我们需要同时为整个旅行确定必须的预订项组,以确保合适的选择可被预约。除了要考虑会议出席者的需要,服务提供商也需要保留一定自主权,并且保持对他们自己资源(本例中是航班、房间和租赁汽车的预约)的控制。

在这个业务领域中,每一个预约的基本要素都互相关联,但不需要被预先决定。很显然,航班没有订下来的话,预订酒店房间和租车就显得毫无意义——除非大会是在本地举办的。而在另外的情况下,预订航班和酒店房间是有意义的,但如果我们订的酒店恰好是会议举行的酒店,那么我们就可以不必费周折来租赁一辆汽车了。

我们也可以希望保持选择未定,先保留若干航班,同时留意其它更直接的旅行方案或者其它方便的酒店。客户寻求数个报价,以便决定提供最低价格的供应商。因而,在单独的原子事务处理中进行整个旅行的安排是不合适的,因为在那种情况下,要么所有的工作都发生,要么就什么都不发生:例如,如果要访问多个航班预订服务,必须有部分结果的产生(放宽的原子性),而这是不可能的。

图 4:旅行安排场景这个例子讨论了业务事务中的需求,这些需求需要一个选择和管理被包含在整体应用程序结果中的任务的机制。出于简单性目的,我们将只考虑放宽用于选择必要航班这个过程的原子性属性;扩展到整个旅行场景的任务,将留给读者作为练习。图 5 展示了此应用程序的配置:每一个航班服务都公开了在某个特定航班上预约、确认或者取消座位的操作。

图 5:系统配置旅行社调用这些服务中的每一个,来取得航班上一个座位的报价。Xantas.com,ALU.com 和 ZA.com 响应了旅行社的航班预定请求(即应用程序级响应)。在本例中(见图 6 ),ALU 和 ZA 的实现只是暂时预定一个座位,而 Xantas 会为客户保留一个实际的座位。Xantas 的服务实现将客户预订信息传送给业务活动协调程序,于是,业务活动协调程序知道它必须在父作用域最终必须撤销整个预约过程或者客户取得更便宜报价的事件发生时,通知相关的参与者进行补偿(“取消预定”座位);其他的服务并不需要补偿,因为它们没有产生任何状态的变更。

图 6:发送请求根据返回的价格,旅行社决定继续并预定由 Xantas 和 ZA 提供的往返航班,如图 7 所示。因为 ALU 并没有保留座位,所以不需要取消 ALU 的航班。

图 7:取消报价因为选中的航班牵扯到 Xantas 和 ZA 两方,旅行社就向 ZA 请求保留一个座位。ZA 确认预约有效。接着,参与者就通知协调程序任务已经完成(如图 8 )。

图 8:选择合适的报价现在,应用程序已经选择了预订的座位,这些座位将被包括在整个预订过程中。你将注意到最后一组选中的参与者必须以原子方式终止。在本例中,ZA 和 Xantas 需要提交事务,并且作为原子组来完成。我们或许能在整个业务应用程序的范围内以原子事务的形式展示这种情况,但相反地,我们选择以一个更简单的场景为例,在这个场景中,旅行社直接执行出结果。

协调程序现在已经收到来自 Xantas.com 和 ZA.com 的确认信息,并且旅行社已经完成了业务事务的请求部分。这样,协调程序就能继续并确认 Xantas.com 和 ZA.com 提供的座位预订的业务活动(如图 9 所示,通过 close)。

图 9:旅行社执行出结果如果 ALU 已经保留了座位,那么旅行社需要指示 ALU 去取消这个预订。然后事务服务将从参与事务的任务中移除 ALU。接下来,旅行社将为剩下的任务确认预订,如图 10 所示。

图 10:旅行社确认报价

结论

人们很早就意识到,ACID 事务本身并不足以被用来构造长时间跨度运行的应用程序。并且,人们已经在开发具体的扩展事务处理模型方面做了很多研究工作。然而,直到 CORBA 活动服务框架出现以前,还没有任何支持构建扩展事务处理的中间件。活动服务提供了一个通用目的的事件信号发射机制,这个机制可以通过编程,允许每个活动以考虑中的模型所规定的方式进行协作。

不幸的是,尽管活动服务也被 J2EE 所采用,但是在这些环境下使用扩展事务处理的机会很少。直到应用程序通常是松耦合而且交互持续几个小时甚至几天的 Web 服务出现以前,对于扩展事务处理的需要已经大大超过了对于传统 ACID 事务的需要[20]。在原来的 OMG 成果中定义的原则,即从具体协议中对通用协作的分离,被人们所接受。Web 服务架构仍处于开发过程中的事实,也意味着 WS-Coordination 规范包含的用于协作的基本需求,尚未有其他地方提供,这也正是 OMG 和 J2EE 对活动服务的接受很缓慢的主要起作用的原因。

值得注意的是,人们在 WS-TX 上的努力,并不是对制定 Web 服务事务处理标准的第一次尝试。早在 2001 年,一个包含了 HP、Oracle 和 BEA 的公司联盟,就开始从事 OASIS 业务事务处理协议(Business Transaction Protocol,BTP)[21]。这个协议是针对于松耦合领域(如 Web 服务)下的业务到业务的事务。这个规范提出了用于事务的两种新模型,要求业务级的决策被容纳进此事务处理基础结构。规范基于这样一个假定:一个单独(两阶段)协议是适合于所有用例的。因为传统的两阶段算法不会对第一阶段和第二阶段之间的运行时间加以限制,所以 BTP 采取这种方式,通过它在这些阶段之间插入业务逻辑决策。这就意味着,在 BTP 中称为 open-top 完成协议的方面需要用户显式地驱动这两个阶段。应用程序对业务合适准备具备完全的控制能力,并且不管使用什么样的业务逻辑,应用程序之后都可以确定确认或者取消那个事务。例如,准备已经成为了服务业务逻辑的一部分。

这项工作并没有成功,因为对于一个协议就可以适用于所有用例的观念,缺乏普遍的接受。因而,基于活动服务的概念,Arjuna、Oracle、Sun Microsystems、IONA 科技公司和富士通等于 2003 年创立了 OASIS Web 服务复合应用程序框架(OASIS Web Services Composite Application Framework)[22]。这个框架和 WS-TX 有相似的目标,并且定义了三个事务处理协议,每一个都针对一个具体用例。

可是,关于正确的方法,人们尚有很多争论。我们真的可以一概而论吗?直接将业务逻辑插入事务处理协议中是否是正确的抽象方法?关于单一协议的论证,主张所有被检验的模型都是两阶段的,尽管各个阶段的名字不尽相同。然而多重协议的支持者则主张,尽管事实上大多数模型都是两阶段的,但是每一个阶段都关联着不同的语义,而最重要的东西恰恰是这些语义。

即便如此,大多数人都同意这样一个观点——多年以来,ACID 事务处理在构建企业应用程序的价值已经变得无法估量了。遗憾的是,它们只适用于在紧耦合的应用程序和环境上运行的短周期活动,对于许多应用程序来说它们被证明很不灵活,而且限制很多。OMG 已经开始进行对扩展事务处理模型的整合工作,这些模型允许放宽 ACID 属性,而且这项工作已经被证实在 Web 服务的舞台上更有价值。

参考资料:

[1] X/Open CAE Specification - Distributed Transaction Processing: The XA Specification, X/Open Document Number XO/CAE/91/300.

[2] Web Services Transaction Technical Committee, OASIS,

[3] J. N. Gray, “The transaction concept: virtues and limitations”, Proceedings of the 7th VLDB Conference, September 1981, pp. 144-154.

[4] D. J. Taylor, “How big can an atomic action be?”, Proceedings of the 5th Symposium on Reliability in Distributed Software and Database Systems, Los Angeles, January 1986, pp. 121-124.

[5] OMG Object Transaction Service, http://www.omg.org/cgi-bin/apps/do_doc?formal/02-08-07.pdf

[6] C. T. Davies, “Data processing spheres of control”, IBM Systems Journal, Vol. 17, No. 2, 1978, pp. 179-198.

[7] A. K. Elmagarmid (ed), “Transaction models for advanced database applications”, Morgan Kaufmann, 1992.

[8] H. Garcia-Molina and K. Salem, “Sagas”, Proceedings of the ACM SIGMOD International Conference on the Management of Data, 1987.

[9] S. K. Shrivastava and S. M. Wheater, “Implementing fault-tolerant distributed applications using objects and multi-coloured actions”, Proc. of 10th Intl. Conf. on Distributed Computing Systems, ICDCS-10, Paris, June 1990, pp. 203-210.

[10] G.Weikum, H.J.Schek, “Concepts and Applications of Multilevel Transactions and Open Nested Transactions”, in Database Transaction Models for Advanced Applications, ed. A.K. Elmagarmid, Morgan Kaufmann, 1992.

[11] G. Alonso, D. Agrawal, A. El Abbadi, M. Kamath, R. Gunthor and C. Mohan, “Advanced transaction models in workflow contexts”, Proc. of 12th Intl. Conf. on Data Engineering, New Orleans, March 1996.

[12] OMG Additional Structuring Mechanisms for the OTS, http://www.omg.org/cgi-bin/apps/do_doc?formal/02-09-03.pdf

[13] I. Houston, M. Little, et al. “The CORBA Activity Service Framework for Supporting Extended Transactions”, Proceedings of Middleware 2001, Heidelberg, 2001.

[14] “J2EE Activity Service for Extended Transactions”, http://www.jcp.org/jsr/detail/95.jsp

[15] BTP Committee specification, http://www.oasis-open.org/committees/business-transaction/ , April 2002.

[16] “A Framework for Implementing Business Transactions on the Web”, Hewlett-Packard initial submission to BTP, March 2001, http://www.oasis-open.org/committee/business-transactions/

[17] “The Business Transactions Protocol. Transactions for a New Age”, Mark Little, in Web Services Journal, Volume 2, Issue 10 (October 2002), pp. 56-60.

[18] “Shootout at the transaction corral; BTP versus WS-T”, http://www.objectwatch.com/issue_41.htm

[19] Results of WS-Transactions Interoperability Workshop,

[20] Business Process Execution Language for Web Services, version 1.1, http://www.oasis-open.org/committees/download.php/2046/BPEL V1-1 May 5 2003 Final.pdf

[21] BTP Committee specification, http://www.oasis-open.org/committees/business-transactions/ , April 2002.

[22] The Web Services Composite Application Framework Technical Committee, http://www.oasis-open.org/committees/documents.php?wg_abbrev=ws-caf

mark.little@jboss.com

注:霍太稳对本译文亦有贡献。

2007-03-26 06:571629
用户头像

发布了 117 篇内容, 共 14.8 次阅读, 收获喜欢 0 次。

关注

评论

发布
暂无评论
发现更多内容

【愚公系列】2022年7月 Go教学课程 013-常量、指针

愚公搬代码

7月月更

没有了可用Task slot,Flink新增任务会怎样?

程序员欣宸

Java flink 7月月更

分享 15 个 Vue3 全家桶开发的避坑经验

pingan8787

Vue Vue3

Qt | QWidget的一些总结

YOLO.

qt 7月月更

一篇文章带你快速学会Flex布局

bo

CSS 前端 Flex 7月月更

LeetCode-数组中数字出现的次数(单身狗问题)

芒果酱

c++ C语言 数据结构算法 Leet Code 7月月更

C# DataGridView数据导出Excel文件

IC00

C# 7月月更

汽车电子行业开发者的内功心法:汽车软件开发V模型(瀑布模型)

不脱发的程序猿

嵌入式开发 瀑布模型 汽车软件开发 V模型

读书笔记之数据密集型应用的可维护性

宇宙之一粟

设计数据密集型应用 7月月更

C#入门系列(二十五) -- 接口

陈言必行

7月月更

试着换个角度理解低代码平台设计的本质

pingan8787

Vue 前端 React 低代码平台

KUDU1.11 环境安装

怀瑾握瑜的嘉与嘉

7月月更 kudu

zookeeper-集群和zab协议

zarmnosaj

7月月更

系统刷JavaScripit 构建前端体系(语法篇)

程序员海军

JavaScript 7月月更

Java核心技术之泛型详解

小明Java问道之路

Java 后端 泛型 Java泛型 7月月更

python小知识-什么是上下文管理

AIWeker

Python python小知识 7月月更

QT|QLabel显示多行文本过多后显示省略号

中国好公民st

qt 7月月更

STM32+DHT11读取温湿度数据显示

DS小龙哥

7月月更

Spring系列一:Spring基础篇

叶秋学长

短视频直播系统源码

开源直播系统源码

短视频源码 直播系统源码 开源源码

VLAN再见,我选择用QinQ!1000字带你详细了解QinQ技术

wljslmz

VLAN 网络技术 7月月更 QinQ

数据平台的发展历程

奔向架构师

大数据 7月月更

Flink实战:消费Wikipedia实时消息

程序员欣宸

Java flink 7月月更

小心!正则 test() 匹配的一个“坑”

掘金安东尼

正则 7月月更

Prometheus 发布 LTS 长期支持版本啦

耳东@Erdong

release Prometheus 7月月更

strcat() - 连接字符串

謓泽

7月月更

Java中的设计模式

Java学术趴

7月日更

使用Flutter开发小程序+App)的一种组合思路

Geek_99967b

小程序

jQuery 请求

Jason199

jquery js post GET 7月月更

qt 实现日历美化

小肉球

qt 7月月更

王者荣耀商城异地多活架构

Pengfei

扩展事务简史_SOA_Mark Little_InfoQ精选文章