Dr. Subrahmanyam Allamaraju
© Subrahmanyam Allamaraju 1999. All rights reserved.
This document is protected by copyright. No part of this document may be reproduced in any form without prior written consent of the author. This document is for electronic distribution only.
All trademarks acknowledged.
译者的声明
(1)版权声明中声明了“未经版权持有者的书面允许不得以任何形式复制本文内容,本文档只以电子版的形式发布”,很显然,版权声明没有限制对电子版的翻译和在网络上传播。
(2)译者对译文不做任何形式的担保。译者对译文不拥有任何权利并且不负担任何义务。
(3)任何人在对译文进行任何处置(包括但不限于复制、传播)之前,应当认真阅读版权声明,译者对其他人的行为不负任何责任。
译序:译者添加的图 6 引自介绍 ORBacus OTS 的网页。译者乃一介草莽,译文中难免存在疏失错讹,祈望仁者指正。
原文: http://www.subrahmanyam.com/articles/transactions/NutsAndBoltsOfTP.html
转载声明:遵守“未经版权持有者的书面允许不得以任何形式复制本文内容,本文档只以电子版的形式发布”,转载者对本文没有任何权力,也对因转载发生的任何行为不负担责任。
介绍
事务管理是对企业应用最紧要的要求之一。在贸易、金融和电子商业领域中,多数大的企业应用依赖于递送它们的商务的事务处理功能。鉴于当今商务对灵活性的要求,在建造、部署和维护企业级别的分布式应用中,事务处理占据的是其中最复杂的部分之一。
本文把以下内容介绍给读者:
什么是事务? 什么是 ACID?
建造一个事务应用的要点是什么? 事务管理中间件为什么很重要?
事务处理应用的典型的体系是怎样的? 体系中的各种构件的职责是什么?
事务处理系统涉及哪些概念?
事务管理领域中有哪些标准和技术?
本文不特定于任何产品,力图在描述各种要点和概念时保持普遍性。本文不打算比较各种事务处理的技术/标准,只是提供对此的一个讨论。
什么是事务?
为了完成对数据的操作,企业应用经常要求并发访问在多个构件之间共享的数据。这些应用在下列条件下应该维护数据的完整性(由应用的商务规则来定义):
分布式访问一个单独的数据资源,以及
从一个单独的应用构件访问分布式资源。
在这种情况,可能要求在(分布式)资源上的一组操作被当作一个工作单元(unit)。在一个工作单元中, 操作的所有部分一起成功或失败并恢复。在下面的情况下这个问题更加复杂:
通过一组分布式的、访问多个资源的数据的构件实现一个工作单元,和/或
部分操作是被顺序执行的或在要求协调和/或同步的并行线程中。
在所有情况下, 都要求应用维护一个工作单元的成功或失败。在失败的情况下,所有资源要把数据状态返回到以前的状态 (比如说,工作单元开始前的状态)。
事务的概念和和事务管理器(或者一个事务处理服务)在一个工作单元中的维护数据完整性,这就简化了这样的企业级别分布式应用的构造。
一个事务是有下列属性的一个工作单元:
原子性(ATOMICITY): 一个事务要被完全的无二义性的做完或撤消。在任何操作出现一个错误的情况下,构成事务的所有操作的效果必须被撤消,数据应被回滚到以前的状态。
一致性(CONSISTENCY): 一个事务应该保护所有定义在数据上的不变的属性(例如完整性约束)。在完成了一个成功的事务时,数据应处于一致的状态。换句话说,一个事务应该把系统从一个一致状态转换到另一个一致状态。举个例子,在关系数据库的情况下, 一个一致的事务将保护定义在数据上的所有完整性约束。
隔离性(ISOLATION): 在同一个环境中可能有多个事务并发执行,而每个事务都应表现为独立执行。串行的执行一系列事务的效果应该同于并发的执行它们。这要求两件事:
在一个事务执行过程中,数据的中间的(可能不一致)状态不应该被暴露给所有的其他事务。
两个并发的事务应该不能操作同一项数据。数据库管理系统通常使用锁来实现这个特征。
持久性(DURABILITY): 一个被完成的事务的效果应该是持久的。
这些属性叫做 ACID 属性,担保一个事务是永远不会不完整,数据永远不会不一致,并发事务是独立的,一个事务的效果是持久的。关于在分布式系统什么能出错的简要的一个描述,请参见 在事务处理系统中的容错和恢复。
建造事务性应用的要点
为了引出在建造事务性应用中涉及的要点,考虑一个定单获得和定单处理应用,它的体系在 图 1 中展示:
这个应用由两个客户构件组成,分别实现定单获得和定单处理操作。这两个操作构成了一个工作或事务单元。分别基于产品,定单,库存清单和货运信息。在这个图中,点断尖头指示的只读的数据访问,而连续尖头指示指示的是修改数据的事务性操作。下面是在这个应用中的事务性操作:
生成定单,
更新库存,
生成货运记录,并
更新定单状态。
当作为一个事务来实现这些操作时,应致力于下述要点:
应用应当与事务性操作和被操作的数据库保持联系。所以应用应该为所有事务定义一个上下文来包含上述四个操作。
因为定单获得和定单处理事务分布于两个构件之上,事务上下文应该是全局的,并通过协议的转换、被从第一个构件传播到第二个。
当事务发生期间,应用应当监控事务的状态。
为了维护事务的原子性,应用构件和/或数据库服务器、应当实现一种机制,在这种机制下对数据库的更改可以被撤消,而又不失去数据的一致性。
为了隔离在共享数据上的并发的事务,数据库服务器应该跟踪被操作的数据,并在一个事务操作期间锁住数据。
应用还应该维护数据库连接和事务之间的关联。
为了实现可靠的锁定,应用构件应向数据库通知事务的终止。
事务处理 - 体系
看到了从头开始建造一个事务性应用的要点,考虑在一个在 图 2 中展示的事务处理体系下建造相同的应用。注意,尽管有多种可能的体系,它们将在后面的章节中讨论, 图 2 中所展示的代表了本质的特征。
`图 2: 事务处理体系
这个体系介入了一个事务管理器和每个数据库(资源)一个的资源管理器。这些构件从应用构件(定单获得和定单处理)中抽象出了特定于事务的大多数要点,并分担事务实现的职责。下面讨论这个体系的各种构件。
应用构件
应用构件:职责
建立和界定事务
传播事务上下文
通过资源管理器操作数据
应用构件是事务性资源的客户。它们是应用开发者用于实现商务事务的程序。
在事务管理器的帮助下,这些构件建立全局事务,如果需要的话传播事务上下文,并在这些事务的范围内操作事务性资源。这些构件不负责实现保护事务的 ACID 属性。但是作为应用逻辑的一部分 ,这些构件通常做是提交还是回滚一个事务的决定。
资源管理器
资源管理器:职责
向事务服务器应征资源
参与两阶段提交和恢复协议
一个资源管理器是一个管理持久和稳定的数据存储系统的构件,并且参与同事务管理器的两段提交和恢复协议。
一个资源管理器典型的是一个稳定的存储系统上的一个驱动器或一个包装,有操作数据的接口(给应用构件), 并且为了参与由事务服务器协调的两阶段提交和恢复协议。这个构件也可以,直接的或间接的,向事务管理器注册资源,这样事务管理器就可以追踪所有参与事务的资源。这个过程叫做资源征集。为了实现两阶段提交和恢复协议,资源管理器应该实现可能被恢复所使用的附加机制。
资源管理器提供两套接口: 一套给应用构件用来连接和完成对数据的操作,另一套给事务管理器用来参与两阶段提交和恢复协议。
事务管理器
事务管理器:职责
建立和维护事务上下文
维护一个事务和特定的资源间的关联
发起并指挥两阶段提交和恢复协议
在开始两阶段提交和恢复过程之前向应用构件们做同步呼叫
事务管理器是一个事务处理环境的核心构件。它的主要职责是当应用构件要求时建立事务,允许资源征集和遣散,并指挥同资源管理器的两阶段提交或恢复协议。
一个典型的事务性应用通过向事务管理器发出一个发起事务的请求来开始一个事务。作为响应,事务管理器开始一个事务并把它同一个呼叫线程联系在一起。事务管理器也建立一个事务上下文。在事务中的所有应用构件和/或线程共享事务上下文。初始发起开始事务的请求的线程,或者如果事务管理器允许的话,任何其他线程可以通过发起提交或回滚请求来最终终止事务。
在一个事务被终止之前,在事务管理器所知道的多个数据上,多个构件和/或线程可以完成事务性操作。如果事务管理器允许的话,在事务最终完成之前,一个事务可以被挂起或被继续执行。
一旦应用发起了提交请求,事务管理器为一个提交操作准备所有资源(通过指挥一次投票表决),并基于是否所有的资源都准备好了(就绪)提交,来发起对所有资源的一个提交或回滚请求。
下面的章节讨论事务处理相关的各种概念。
事务处理 - 概念
事务界定
指定一个事务叫做事务界定(demarcation),通过把分布式的构件绑定到一个全局事务上来完成事务界定工作,它是标记构成一个事务的一组操作的一种方法。
最常用的界定的途径是为事务处理标记执行操作的线程。这叫做编程界定。这样建立的事务可以通过去除标记而被挂起,并在以后通过从挂起点向恢复点显式的传播事务上下文来恢复执行。
事务界定在向事务管理器的一个提交或一个回滚请求之后结束。提交请求指导所有参与的资源管理器永久的记录事务中的操作的效果。回滚请求使资源管理器撤消事务中所有操作的效果。
一个可替代编程界定的是声明界定。基于构件的事务处理系统如 Microsoft 事务服务器、和基于应用服务器的事务处理系统如企业 Java Beans 规范支持声明界定。在这种技术中,构件在部署时被标记为事务性的。这暗示了两件事。首先,界定的职责从应用转移到了容纳构件的容器(container)。为此,这种技术也叫做管理容器界定。其次,界定从应用建造期间(静态)延期到构件部署期间(动态)。
事务上下文和传播
因为多个应用构件和资源参与了一个事务,对于事务管理器建立和维护发生的事务的状态是必须的。这通常以事务上下文的形式完成。
事务上下文是在资源上的事务性操作和调用操作的构件之间的一个关联(association)。在一个事务执行期间,所有的参与事务的线程共享事务上下文。所以事务上下文在逻辑上封装(envelop)了在一个事务期间在事务性资源上的完成的所有操作。事务上下文通常由底层的事务管理器透明的维护。
资源征集
资源征集是资源管理器向事务管理器报告它们参与一个事务的过程。这个过程使事务管理器可以跟踪参与一个事务的所有资源。资源管理器使用这些信息协调资源管理器完成的事务性工作,以及驱动两阶段提交和恢复协议。
在事务结束时(一个提交或回滚之后)事务管理器遣散资源。在此之后,不再保持事务与资源之间的关联。
两阶段提交
这个事务管理器与所有应征一个事务的资源之间的协议确定是所有的资源管理器都提交事务还是它们都终止(abort)。在这个协议中,当应用要求提交事务时,事务管理器向所有涉及的资源管理器发起一个准备请求 。每个这些资源可以依次发送一个回应来指示出它是否准备好(就绪)提交。只有当所有的资源管理器都准备好提交,事务管理器才向所有的资源管理器发起一个提交请求。否则,事务管理器发起一个回滚请求接着事务被滚回来。
事务处理 - 标准和技术
X/Open 分布式事务处理模型
X/Open 分布式事务处理(DTP)模型是 Open Group 提出的一个分布式处理模型,Open Group 是一个厂商财团。这个模型是在事务处理和数据库领域中多数商业厂商间的一个标准。
这个模型由四个构件组成:
应用程序:实现事务性操作。
资源管理器:同于上面的讨论。
事务管理器:同于上面的讨论。
通信资源管理器:方便在不同的事务处理领域中的不同的事务管理器之间的互操作。
这个模型还定义了下列接口:
TX 接口: 这是应用程序和事务管理器之间的接口,并由事务管理器实现。这个接口提供事务界定服务,允许应用程序把事务性操作绑定到一个全局事务中。这个接口由下列函数组成:
表 1: X/Open 模型的 TX 接口
函数
功能
tx_open
打开一个事务管理器和相关联的一组资源管理器。
tx_close
关闭一个事务管理器和相关联的一组资源管理器。
tx_begin
开始一个新事务。
tx_rollback
回滚事务。
tx_commit
提交事务。
tx_set_commit_return
提交事务。(译注:原文如是)
tx_set_transaction_control
在链状和非链状模式间选择。在链状事务的情况下,工作被分成片段(piece),每个片段在一个平坦的(flat)事务控制之下。一旦完成了工作的一个片段,这个片段的提交或回滚不依赖于其他的片段的状态。
tx_set_transaction_timeout
设置一个事务超时间隔。
tx_info
返回事务信息,如它的标识符、事务的状态等。
XA 接口: 这是一个资源管理器和事务管理器之间的双向接口。这个接口规定了两套函数。第一套叫 xa_*() 函数,由资源管理器实现,被事务管理器使用。
表 2: X/Open DTP 模型中的事务管理器的 XA 接口
函数
功能
xa_start
指导一个资源管理器把应用程序的后续的请求与一个被提供的标识符所标识的事务关联起来。
xa_end
结束一个资源管理器与一个事务的关联。
xa_prepare
资源管理器为提交操作做准备。由事务管理器发起,是两阶段提交操作的第一阶段。
xa_commit
提交事务性操作。由事务管理器发起,是两阶段提交操作的第二阶段。
xa_recover
检索一个就绪的(prepared)列表,启发式的(heuristically)提交或启发式的回滚事务。
xa_forget
忘记同给定事务标识符相关联的启发式(heuristic)事务。
第二套函数叫 ax_*() 函数,由事务管理器实现,被资源管理器使用。
表 3: X/Open DTP 模型中的资源管理器的 AX 接口
函数
功能
ax_reg
动态的向一个事务管理器应征。
ax_unreg
动态的从一个事务管理器撤出。
XA+ 接口: 这个接口被用于支持通过通信资源管理器来跨越不同的事务管理器的全局事务。
TXRPC 接口: 这个接口提供在一个全局事务中的不同的应用程序之间通信的可移植性。
CRM-OSI TP: 是一个通信资源管理器和 OSI 事务处理服务之间的接口。
X/Open DTP 模型在产业界中被确立的。一些商业事务管理产品,象 TXSeries/Encina (完全附属于 IBM 的 Tranarc 的产品), Tuxedo 和 TopEnd (BEA Systems 的产品), 还有 AT&T GIS 支持 TX 接口。尽管 Microsoft 的 Transaction Server 不支持 TX 接口,它还是能够同象 Oracle 这样的遵从 XA 的数据库互操作。类似的,多数商业数据库象 Oracle, Sybase, Informix 和 Microsoft SQL Server, 以及消息中间件产品如 IBM 的 MQSeries, 和 Microsoft 的 MSMQ Server 提供了 XA 接口的一个实现。
OMG 对象事务服务
对象事务服务(OTS)是由对象管理组织(OMG)规定的分布式事务处理服务。这个规范扩展了 CORBA 模型并定义了一系列跨越(across)多个 CORBA 对象完成事务处理的接口。
OTS 模型基于 X/Open DTP 模型之上并提供下列增强:
OTS 模型把函数形式的 XA 和 TX 接口替换成了 CORBA IDL 接口。
在这个模型中的各种对象通过在 IIOP 之上的 CORBA 方法调用来通信。
OTS 可以同 X/Open DTP 模型互操作。一个使用了事务性对象的应用可以使用事务管理器的 TX 接口来进行事务界定。
OTS 体系由下列构件组成:
事务客户: 一个调用事务性对象上的操作的程序或对象。
事务性对象: 一个封装(encapsulate)或参照(refers to)持久数据的 CORBA 对象,并且它的行为依赖于在一个事务期间是否调用它的操作。
可恢复对象: 一个直接维护持久数据并且参与事务协议的事务性对象。
事务性服务器: 一个或多个事务性对象的集合(collection)。
可恢复服务器: 一个对象的集合,其中至少有一个是可恢复的。
资源对象: 一个资源对象是为了参与两阶段提交和恢复协议而被注册的、在事务服务中的一个对象。
除了通常的事务性语义,CORBA OTS 还提供了下面的:
嵌套事务: 这就允许一个应用建立一个嵌入在一个现存的事务中的事务。在这个模型中,多个子事务(subtransaction)可以递归的嵌入一个事务中。子事务可以提交或回滚而不提交或回滚它的父事务。 但是,一个提交操作的结果要视事务的所有祖先的提交(commitment)状况而定。这个模型的主要优点是可以在一个精细的粒度上控制事务性操作。应用有一个在子事务层次上对错误进行改正或补偿的机会,而不用真正的去尝试提交整个父事务。
应用同步: 使用 OTS 同步协议,在两阶段提交过程开始之前和完成之后,特定的对象可以为了通告而被注册在事务服务上。这使得应用对象可以同步暂时的(transient)状态和存储在持久存储中的数据。
图 6: ORBacus® OTS 体系 (译者添加)
下面是 CORBA OTS 规范的原理上的接口:
表 4: CORBA OTS 接口
接口
职责
Current
事务界定 (begin, commit, rollback, rollback_only, set_time_out)
事务的状态 (get_status)
事务的名字 (get_transaction_name)
事务上下文 (get_control)
TransactionFactory
显式的事务建立
Control
显式的事务上下文管理
Terminator
提交或回滚一个事务
Coordinator
事务的状态 (get_status, get_parent_status, get_top_level_status)
事务的信息 (is_same_transaction, is_related_transaction, is_ancestor_transaction, is_descendant_transaction, is_top_level_transaction, hash_transaciton, hash_top_level_transaction, get_transaction_name, get_txcontext)
资源征集 (register_resource, register_subtrans_aware)
同步对象的注册 (register_synchronization)
为回滚而设置对象 (rollback_only)
建立子事务 (create_subtransaction)
RecoveryCoordinator
在失败的情况下协调恢复 (replay_completion)
Resource
参与两阶段提交和恢复协议 (prepare, rollback, commit, commit_one_phase, forget)
Synchronization
在两阶段提交开始之前和完成之后的应用同步 (before_completion, after_completion)
SubtransactionAwareResource
提交或回滚一个子事务 ,被事务服务调用 (commit_subtransaction, rollback_subtransaction)
TransactionalObject
所有事务性对象都实现的一个指示器(marker)接口
下述产品提供 OTS 的实现: Integrated Transaction Service (Inprise 的产品), OrbixOTM (Iona 的产品), OTSARjuna (Arjuna Solutions Limited 的产品), 和 TPBroker (Hitachi Software 的产品).
JTS 和 JTA
Java 事务服务 和 Java 事务 API 是分布式计算领域中最新的竞争参加者。作为企业 Java 的发起者,Sun Microsystems Inc. 在 1999 年提出了规范。(译注:1999年12月8日推出正式规范)
图 3: Java 事务的发起
JTS 规定一个 Java 事务管理器的实现。这个事务管理器支持 JTA,应用服务器可以使用它建造支持事务性 Java 的应用。 JTS 的内部实现 OMG OTS 1.1 规范的 Java 映射。Java 映射被规定在两个包中: org.omg.CosTransactions 和 org.omg.CosTSPortability。尽管 JTS 是 OMG OTS 1.1 规范的一个 Java 实现,JTA 仍是简化了的 X/Open DTP 模型中的 XA 和 TX 的函数形式的接口。
JTA 规定一个建造事务性应用服务器的体系,并为这个体系中各种构件定一系列的接口。 这些构件是: 应用构件, 资源管理器, 应用服务器, 它们在 图 3 中展示。
JTS 为事务性应用服务器和应用提供了一个新的体系,而在内部遵从 OMG OTS 1.1 接口。这就允许遵从 JTA 的应用程序同其他的遵从 OTS 1.1 的应用程序通过标准的 IIOP 来互操作。
象在 图 3 中展示的那样,在 Java 事务模型中,Java 应用构件能通过 JTS 在遵从 JTA 的资源上指挥事务性操作。JTS 扮演的是 OTS 之上的一个薄层。应用可以发起全局事务来包含其他 OTS 事务管理器,或参与到一个其他遵从 OTS 的事务管理器发起的全局事务。
关于 JTS 和 JTA 的更详细的叙述请参见 Java 事务服务。
Microsoft 事务服务器
Microsoft 事务服务器(MTS) 是一个基于构件的事务服务器,它的构件基于 Microsoft 的 构件对象模型 (COM)。MTS 编程模型为建造事务性 COM 构件提供接口,而 MTS 运行环境提供一个部署和管理这些构件和管理事务的方法。使用了 MTS,由多个 COM 构件做的工作可被组合在一个单一的事务中。
不象本章讨论的其他技术,MTS 是一个产品并且不基于开放的规范。还要注意,尽管 MTS 环境提供了一些其他特征,如资源缓冲池(pooling), 对象重复利用(recycling), 访问控制等,本节只聚焦于 MTS 的事务性的功能,并尝试把各种事务管理的概念映射到 MTS 环境。
MTS 体系
高层的 MTS 体系在 图 4 中展示:
图 4: Microsoft 事务服务器
MTS 环境由下列部分组成:
MTS 运行时环境(run-time): 它是 MTS 构件的实例执行和被管理的环境。 MTS 运行时环境提供了 MTS 构件的部署和管理。它有以下特征:
分布式事务的管理
过程和线程的原子性管理
对象的(建立,缓冲(pooling)和重用)管理
控制对象的建立和使用的分布式安全服务
MTS Explorer: 这是一个图形用户界面驱动的工具,用来在 MTS 运行环境上部署和管理 MTS 构件。MTS Explorer 也被用于通过分布式事务协调器来监控事务。
分布式事务协调器(DTC): DTC 是 MTS 的事务管理器。
MTS API: MTS API (在 Microsoft Visual Basic, Microsoft Visual C++ 和 Microsoft Visual J++ 中) 为建造事务性构件提供特定的接口和特定的具体的类。
资源分发器(dispenser): 一个 MTS 资源分发器代表 MTS 应用来管理非持久的共享的数据。MTS 提供两个资源分发器:
ODBC 资源分发器: ODBC 资源分发器本质上是一个 ODBC 驱动器的管理器,并有下列附加功能 :
管理到遵从 ODBC 的数据库的连接的缓冲池,包括连接的回收和重用。
征集和遣散在 MTS 上下文对象上的数据库连接。
共享的属性管理器: MTS 共享的属性管理器管理应用范围的特定于进程的属性(一对名字-值) 并提供同步的访问这个数据。
资源管理器: 对于一个参与 MTS 事务的资源管理器,它必须支持下列协议之一:
OLE 事务: 这是一个基于 COM 的两阶段提交协议,资源管理器使用它来参与由 DTC 协调的事务。
X/Open DTP XA 协议: 对于这个协议,MTS 要求一个 OLE 事务到 XA 的映射器(mapper)。这个映射器在 MTS SDK 中提供。
MTS 对象和事务上下文
一个 MTS 对象是一个 MTS 构件的一个实例(一个构件在 MTS 上被部署,并被 MTS 管理)。对于每个 MTS 对象,MTS 建立和维护一个上下文对象(ObjectContext),它为一个 MTS 对象提供执行上下文。上下文对象也维护事务上下文的信息。资源分发器和 DTC 可以为事务界定,资源征集,遣散,两阶段提交等,访问这个事务上下文信息。注意,在 MTS 中,为每个 MTS 对象都维护事务上下文信息,而不是为所有参与一个事务的对象维护一个单一的事务上下文对象。
事务结果
每个 MTS 对象可以通过调用 ObjectContext 对象的一个方法,来参与决定一个事务的结果(outcome):
SetComplete: 通知 MTS,对象已经成功的完成了它的工作,它的工作可以被提交了。
SetAbort: 通知 MTS,对象的工作不能被提交。
EnableCommit: 对象的工作不是必须做完,但它的事务性工作可以用当前的形式被提交。
DisableCommit: 通知 MTS,对象的工作不能用当前的形式被提交。
事务界定
MTS 同时允许事务的编程界定和声明界定。对于在 MTS 上部署构件,声明界定是强制的。除此之外,MTS 客户也可以通过编程发起和结束事务。
声明界定: 依靠一个 MTS 构件的事务属性(property),MTS 代表应用自动的开始一个事务。可能以有下列的事务属性 (可以在部署期间设置):
要求事务: 构件的实例总是在一个事务的上下文中执行。希望调用(调用)对象在一个事务的上下文中被执行。
要求新事务: 构件的实例必须在它们自己的事务中执行,而不考虑调用对象是否已经开始了一个事务。
支持事务: 构件的实例可以在调用对象的事务(如果有的话)范围内执行。这暗示构件是事务安全的。
不支持事务: 构件的实例不在任何事务的范围内执行。MTS 不把这样的构件做的工作同任何事务关联在一起。
编程界定: MTS 客户可以使用 TransactionContext 对象用程序界定事务。一个客户可以通过建立TransactionContext 对象的一个实例来开始一个事务,并通过调用这个对象的 Commit 或 Abort 方法来结束事务。所有在这些使用 TransactionContext 对象的边界内建立的 MTS 对象将在同一个事务上下文下执行。(除非构件设置为要求一个新事务或不支持事务)。 MTS 隐含的维护 TransactionContext 对象和事务的关联。
资源征集
MTS 进行自动的资源征集。当一个 MTS 对象向资源分发器要求到一个资源的连接时,资源分发器获取调用对象的事务上下文,并用来它注册连接。
经管 MTS 只能在 Microsoft Windows 平台上获得,MTS 可以同遵循 XA 协议的资源管理器互操作,并且在非 Windows 平台上操作的这样的资源管理器可以参与由 DTC 协调的事务。
关于 MTS 的更多的信息请参阅 MSDN library。 要得到 MTS 和其他竞争技术的一个快速而详细的特征汇编请参阅 MTS FAQ.
企业 Java Beans
企业 Java Beans (EJB) 是来自 Sun Microsystems Inc 的一个技术规范。它规定了一个建造基于构件的分布式应用的框架。在过去六个月中,符合这项技术的应用服务器已经从不同的厂商出现,而规范当前由 Sun Microsystems Inc 来不断改善。(译注:1998年3月24日推出正式的规范1.0).
作为一个应用服务器框架,EJB 服务器致力于事务处理,资源缓冲池,安全,线程,持久性,远程访问, 生命周期等。但是同于 MTS 的情况,本节只聚焦于 EJB 框架的分布式事务性模型。
EJB 框架规定叫做 enterprise beans 的构件的构造,部署和激发。EJB 规范把 enterprise beans 分成两类: 实体(entity) beans 和 任务(session) beans。实体 beans 抽象的是持久域数据,任务 beans 提供特定的应用逻辑的任务。两种类型的 beans 被遵循 EJB 的服务器在叫做容器的东西中维护。一个容器为 enterprise beans 提供运行时环境。
图 5 展示了一个遵循 EJB 的应用服务器的简化了的体系。图中只展示了体系的各组成部分间的本质性的交互。
图 5: 在 EJB 应用服务器中的事务
一个 enterprise bean 由两个接口来指定: home 接口和 remote 接口。home 接口指定如何建立和查找一个 bean。通过这个接口,一个客户或其他 bean 可以获得驻留在一个 EJB 服务器上某个容器中的某个 bean 的一个引用。 remote 指定特定于应用的与实体或任务 bean 相关的方法。
客户可以通过 Java 命名和目录接口 (Java Naming and Directory Interface: JNDI)机制获得 enterprise bean 的 home 接口的引用。一个 EJB 服务器应当为任何命名和目录服务器提供一个 JNDI 实现。通过使用这个到 home 接口的引用,一个客户可以获得到 remote 接口的一个引用。客户可以接着访问在这个 remote 接口中指定的方法。EJB 规范规定 Java 远程方法激发(Remote Method Invocation: RMI) 作为远程方法激发的应用层的协议。但是,一个实现可以使用 IIOP 作为线路层(wire-level)协议。
在 图 5 中,客户首先获得到 home 接口的一个引用,接着通过 home 接口获得到到 Bean A 的一个实例的一个引用。Bean A 的一个实例获得到 Bean B 的一个实例的一个引用并调用在其上的方法适用相同过程。
EJB 事务模型
EJB 框架不规定特定于任何事务服务(例如 JTS) 或协议的事务管理。但是,规范要求把 JTS 的 javax.transaction.UserTransaction 接口暴露给 enterprise bean。下面的段落讨论的编事务界定要求这个接口。
类似于 MTS,EJB 框架提供了事务的声明界定。容器依靠在一个容器中部署一个 enterprise 的时候指定的属性(attribute),来自动完成界定。
下列属性确定如何创建一个事务。
不支持: 容器不在一个全局上下文中调用 bean。
要求: 容器在一个全局上下文中调用 bean。如果调用线程已经有一个相关联的事务上下文,容器在同一个事务上下文中调用 bean 。否则,容器建立一个新事务并在这个事务上下文中调用 bean。
支持: bean 是事务就绪的。如果客户在一个事务中调用 bean,bean 也在相同的事务中被调用。否则,不在一个事务上下文中调用 bean。
要求新的: 不管客户是否与一个事务相关联,容器在一个新事务中调用 bean。
强制: 容器必须在一个事务中调用 bean。容器应该在调用任何在 bean 上的方法之前开始一个事务。
事务界定
EJB 框架支持三类事务界定。
声明界定: 这也叫容器管理的界定。容器界定代表 bean 界定事务。在一个 EJB 服务器上部署 bean 的时候指定要求的属性。bean 可以用 javax.ejb.EJBContext.setRollbackOnly() 方法来为回滚而标记事务。
Bean 管理的界定: 这类似于客户管理的界定。
客户管理的界定: Java 客户可使用 javax.transaction.UserTransaction 接口来编程的界定事务。
资源征集
EJB 自动执行资源征集。EJB 容器在一个 bean 获得一个连接时、自动的把连接应征到 EJB-aware 的资源管理器上。
应用同步
EJB 规范为应用同步提供 javax.ejb.SessionSynchronization 接口。当它被一个 bean 所实现,容器为在两阶段提交期间的应用同步而调用 afterBegin, beforeCompletion 和 afterCompletion 方法。
当前有一些厂商提供遵循 EJB 1.0 规范的应用服务器。这样的产品有 BEA Systems Inc. 的 WebLogic, GemStone Systems Inc. 的 GemStone/J, Sun Microsystems Inc. 的 NetDynamics, Oracle Corporation 的 Oracle Application Server, 和 Persistence Software Inc. 的 PowerTier for EJB。 请参阅 EJB Directory 来得到一个 EJB 应用服务器和 EJB-aware 数据库的列表。规范当前正在经历一次较大的彻底检修,遵循新标准的产品有望在1999年底或2000年初推出(译注: 1999年12月17日推出了规范1.1,当前的规范是2.0)。
总的来说,EJB 框架提供了极其类似于 MTS 的特征。两种技术都允许基于构件的事务性分布式应用,并从应用构件中抽象出事务界定的过程。
结论
事务处理一直是复杂的和致关重要的。但是随着 MTS 和 EJB 的到来,事务处理同时抓住了开发者和 IT 组织的兴趣和注意。这不是没有道理的。这些新近的技术简化了分布式事务管理,并为三个重要的开发供给了燃料:
分布式计算: 两个竞争的分布式计算模型(CORBA 和 COM/DCOM) 简化了分布式计算。
基于构件的开发: 基于上述的接口为中心的范例(paradigm), 和基于构件的分布式应用开发成为了现实。
面向对象: 设计模式和框架促进了面向对象编程的成熟,面向对象使实现这些技术成为可行的。
除此之外,这些技术还致力于当今企业应用要求的可伸缩性和健壮性。
本文的目标是聚焦于分布式事务管理中涉及的要点和概念。本文不能足够全面的覆盖这些底层技术的所有详细细节。同时,本文不打算比较技术,但尝试着把多种概念映射到每一种技术上。只讨论了 nuts 和 bolts,而不是如何建造它们以及用它们建造怎样的机器。