下载第 19章 ASP和事务性 Web应用程序在许多大型、关键的应用程序中,计算机每秒钟都在执行大量的任务。更为经常的不是这些任务本身,而是将这些任务结合在一起完成一个业务要求,称为事务。如果能成功地执行一个任务,而在第二个或第三个相关的任务中出现错误,将会发生什么?这个错误很可能使系统处于不一致状态。这时事务变得非常重要,它能使系统摆脱这种不一致的状态。
M i c r o s o f t最初使用 M i c r o s o f t事务服务器 ( M T S )来处理事务。随着 Windows 2000的发布,
M i c r o s o f t进一步改进了 M T S,使其成为 C O M +的一部分或组件服务。
本章讲述组件服务的事务性特性。了解它们如何用于支持在 I I S上开发的应用程序的事务。
本章的主要内容包括:
事务处理的定义。
事务处理的目的。
在 C O M +中的事务处理如何工作。
事务性 A S P页面。
首先,让我们看一看什么是事务处理。
19.1 事务处理的定义本书已经介绍了许多涉及事务处理的概念,但是事务处理到底是什么。在大型机时代,
就有事务处理。用户信息控制系统 ( C I C S ),Tu x e d o和 To p E n d等产品都是事务处理系统的例子,
它们为应用程序提供事务服务。
为了讨论事务处理,必须首先定义事务。
事务是一个最小的工作单元,不论成功与否都作为一个整体进行工作。
不会有部分完成的事务。由于事务是由几个任务组成的,因此如果一个事务作为一个整体是成功的,则事务中的每个任务都必须成功。如果事务中有一部分失败,则整修事务失败。
当事务失败时,系统返回到事务开始前的状态。这个取消所有变化的过程称为“回滚”
( r o l l b a c k )。例如,如果一个事务成功更新了两个表,在更新第三个表时失败,则系统将两次更新恢复原状,并返回到原始的状态。
19.1.1 保持应用程序的完整性任何应用程序的关键是要确保它所执行的所有操作都是正确的,如果应用程序仅仅是部分地完成操作,那么应用程序中的数据,甚至整个系统将会处于不一致状态。例如,看一下银行转账的例子,如果从一个帐户中提出钱,而在钱到达另一个帐户前出错,那么在此应用程序中的数据是错误的,而且失去了它的完整性,也就是说钱会莫名其妙地消失。
克服这种错误有两种方法:
在传统的编程模型中,开发者必须防止任何方式的操作失败。对任何失败点,开发者必须加上支持应用程序返回到这一操作开始前的状态的措施。换句话说,开发者必须加入代码使系统能够在操作出现错误时恢复原状 (撤消 )。
更为简单的方法是在事务处理系统的环境之内进行操作,事务处理系统的任务就是保证整个事务或者完全成功,或者什么也不做。如果事务的所有任务都成功地完成,那么在应用程序中的变化就提交给系统,系统就处理下一个事务或任务。如果操作中某一部分不能成功地完成,这将使系统处于无效的状态,应回滚系统的变化,并使应用程序返回到原来的状态。
事务处理系统的能力就是将完成这些操作的知识嵌入到系统本身。开发者不必为将系统恢复原状编写代码,需要做的只是告诉系统执行任务是否成功,剩下的事情由事务处理系统自动完成。
在帮助开发人员解决复杂的问题时,事务处理系统的另一好处是其 A C I D属性。
19.1.2 ACID属性当事务处理系统创建事务时,将确保事务有某些特性。组件的开发者们假设事务的特性应该是一些不需要他们亲自管理的特性。这些特性称为 A C I D特性。
A C I D就是:原子性 ( A t o m i c i t y )、一致性 ( C o n s i s t e n c y )、隔离性 ( I s o l a t i o n )和持久性
( D u r a b i l i l y )。
1,原子性原子性属性用于标识事务是否完全地完成,一个事务的任何更新要在系统上完全完成,
如果由于某种原因出错,事务不能完成它的全部任务,系统将返回到事务开始前的状态。
让我们再看一下银行转帐的例子。如果在转帐的过程中出现错误,整个事务将会回滚。
只有当事务中的所有部分都成功执行了,才将事务写入磁盘并使变化永久化。
为了提供回滚或者撤消未提交的变化的能力,许多数据源采用日志机制。例如,
SQL Server使用一个预写事务日志,在将数据应用于 (或提交到 )实际数据页面前,先写在事务日志上。但是,其他一些数据源不是关系型数据库管理系统 ( R D B M S ),它们管理未提交事务的方式完全不同。只要事务回滚时,数据源可以撤消所有未提交的改变,那么这种技术应该可用于管理事务。
2,一致性事务在系统完整性中实施一致性,这通过保证系统的任何事务最后都处于有效状态来实现。如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。因为事务开始时系统处于一致状态,所以现在系统仍然处于一致状态。
再让我们回头看一下银行转帐的例子,在帐户转换和资金转移前,帐户处于有效状态。
如果事务成功地完成,并且提交事务,则帐户处于新的有效的状态。如果事务出错,终止后,
帐户返回到原先的有效状态。
记住,事务不负责实施数据完整性,而仅仅负责在事务提交或终止以后确保数据返回到一致状态。理解数据完整性规则并写代码实现完整性的重任通常落在开发者肩上,他们根据业务要求进行设计。
第 1 9章 A S P和事务性 We b应用程序 计计 559下载当许多用户同时使用和修改同样的数据时,事务必须保持其数据的完整性和一致性。因此我们进一步研究 A C I D特性中的下一个特性:隔离性。
3,隔离性在隔离状态执行事务,使它们好像是系统在给定时间内执行的唯一操作。如果有两个事务,运行在相同的时间内,执行相同的功能,事务的隔离性将确保每一事务在系统中认为只有该事务在使用系统。
这种属性有时称为串行化,为了防止事务操作间的混淆,必须串行化或序列化请求,使得在同一时间仅有一个请求用于同一数据。
重要的是,在隔离状态执行事务,系统的状态有可能是不一致的,在结束事务前,应确保系统处于一致状态。但是在每个单独的事务中,系统的状态可能会发生变化。如果事务不是在隔离状态运行,它就可能从系统中访问数据,而系统可能处于不一致状态。通过提供事务隔离,可以阻止这类事件的发生。
在银行的示例中,这意味着在这个系统内,其他过程和事务在我们的事务完成前看不到我们的事务引起的任何变化,这对于终止的情况非常重要。如果有另一个过程根据帐户余额进行相应处理,而它在我们的事务完成前就能看到它造成的变化,那么这个过程的决策可能建立在错误的数据之上,因为我们的事务可能终止。这就是说明了为什么事务产生的变化,
直到事务完成,才对系统的其他部分可见。
隔离性不仅仅保证多个事务不能同时修改相同数据,而且能够保证事务操作产生的变化直到变化被提交或终止时才能对另一个事务可见,并发的事务彼此之间毫无影响。这就意味着所有要求修改或读取的数据已经被锁定在事务中,直到事务完成才能释放。大多数数据库,
例如 SQL Server以及其他的 R D B M S,通过使用锁定来实现隔离,事务中涉及的各个数据项或数据集使用锁定来防止并发访问。
4,持久性持久性意味着一旦事务执行成功,在系统中产生的所有变化将是永久的。应该存在一些检查点防止在系统失败时丢失信息。甚至硬件本身失败,系统的状态仍能通过在日志中记录事务完成的任务进行重建。持久性的概念允许开发者认为不管系统以后发生了什么变化,完成的事务是系统永久的部分。
在银行的例子中,资金的转移是永久的,一直保持在系统中。这听起来似乎简单,但这,
依赖于将数据写入磁盘,特别需要指出的是,在事务完全完成并提交后才写入磁盘的。
所有这些事务特性,不管其内部如何关联,仅仅是保证从事务开始到事务完成,不管事务成功与否,都能正确地管理事务涉及的数据。
19.2 分布式事务总体来看,如果所有数据的修改仅依靠单个数据源就能完成,则这个事务就相当简单了。
然而,随着商业需求的日益增加,应用程序变得越来越复杂,经常需要访问多个数据库,这些数据库通常分布在不同的地方,这就是分布式事务。分布式事务修改的数据存储在多个或多种类型的数据源中,这些数据源分布在多台机器上,甚至更复杂的情况。
设想有一个事务,要求数据变化发生在两个分离的数据库中,仍然要求所有的 A C I D特性
560计计 ASP 3 高级编程 下载测试能够满足。基本的事务处理不能满足要求,因为如果其中一个数据库服务器失败,无法确保另外一个数据库的数据还没有提交并成为永久的。换句话说,无法协调发生在不同地方的多个事务处理就没有办法保证事务的原子性。
例如,运行在机器 A上的一个组件是单个事务的组成部分之一,组件能够利用机器 B上的
SQL Server执行数据库事务。组成事务的另一组件用运行在机器 C上的 O r a c l e服务器执行数据库事务。这三台机器运行着四块不同的代码,它们全都要参与到这个事务中。
即使通过 C O M +隐藏分布式事务中的细节,也必要研究和了解分布式事务的“幕后”结构。请记住这些 A C I D特性适用于所有类型的事务,不论事务涉及的数据库是什么类型或数量有多少。
使用 MS DTC进行两阶段提交让我们再看一下上述分布式事务的例子。如果 O r a c l e服务器停机了,如何保证事务的原子性。答案是使用两阶段提交 (two-phase commit,2 P C )和通过 M i c r o s o f t分布式事务协调器 ( M S
D T C )协调。
MS DTC是最先集成在 SQL Server中,现在已成为 C O M +必不可少的部分,通过在事务处理中加入其他的因子,MS DTC确认所有的过程完成并提交他们。
让我们进一步研究 MS DTC,了解其工作方式。为了能用两阶段提交协议进行协调,事务中的每个数据源必须装有 MS DTC。在这些安装中,主要的协调器总是在事务的起源之处。这个主要的协调器称为提交协调器,它负责确保事务的提交或终止。不管事务是成功地提交还是回滚,提交协调器都负责向客户应用程序返回一个报告。
在两阶段提交中第一阶段是准备阶段,每个服务器执行它接收的指令,但所有应写到磁盘的内容都被缓冲,如图 1 9 - 1所示。
一旦服务器已执行了指令,就通知提交协调器关于事务的状况,如图 1 9 - 2所示。
第 1 9章 A S P和事务性 We b应用程序 计计 561下载图 19-1 准备阶段 图 19-2 通知提交协调器关于事务的状况图 19-3 提交协调器提交事务 图 19-4 事务回滚事务开始更新成功提交 提交终止回滚到原始状态提交事务执行插入更新准备提交准备提交插入更新提交协调器提交协调器 提交协调器提交协调器第二阶段称为提交阶段。如果提交协调器接收到来自每个数据源的“准备提交”通知,
就提交事务,如图 1 9 - 3。
然而,如果从某一受影响的数据源接收到失败信息,提交协调器将执行回滚,并且通知客户应用程序,见图 1 9 - 4。
19.3 事务性 C O M +应用程序在前几章我们已经看到 C O M +提供的几种运行期特性,它们使得分布式组件的开发简单化,这些组件可用于创建可扩展、可维护的 A S P应用程序。 M T S最先引进了事务模型,它的设计简化了基于组件的分布式事务处理系统的开发。作为 M T S的继承者,C O M +增强并扩充了 M T S的强大的事务模型,给系统提供更多灵活性和简单化。
C O M +事务模型去掉了复杂的事务处理代码,这些代码是通过 MS DTC协调分布式事务所必需的。但是更重要的是,C O M +事务模型透明地融合了分布式事务与 C O M +组件。
通过使用声明 ( d e c l a r a t i v e )属性实现的 C O M +事务,有时也称为声明事务或自动事务。声明属性能从外部指定到组件的实现。为此,必须:
配置组件的 Transaction Support属性,使用 Component Services Explorer或者在组件类型库中使用一个常数值。
可选修改组件来表决事务的结果。
通过代表组件与 MS DTC交互,C O M +自动地处理其余的复杂且冗长的事务细节。
因为 C O M +依赖于 MS DTC协调事务,单个组件能够在单个 C O M +事务中对不同类型的数据源执行操作。当与组件一起使用 C O M +声明事务时,能影响 A D O或 OLE DB数据访问。在单个事务中能够操作的数据源的可能组合是无止境的。例如,C O M +对象能够在 SQL Server数据库中修改数据、发送 M S M Q消息,以及操作来自大型机系统的数据,所有这一切都在相同的
C O M +事务中。
现在我们明白了 C O M +事务的益处,下面继续学习如何有效地使用声明事务模型并了解
C O M +在“幕后”所做的事。
19.3.1 Transaction Support属性正如上面提到的,每个 C O M +组件的 Transaction Support属性决定了组件将如何参与
C O M +事务。激活 C O M +对象时,C O M +决定了对象的事务支持以及创造者是否已经提供了一个存在的事务。基于这两方面的信息,C O M +运行期将在一个存在的事务或一个新的事务中提供对象,或者根本不存在事务。不管有没有事务,都能激活每一个 C O M +对象。由于这个原因,利用事务的组件常常被称为事务性组件,没有利用事务的组件则称为非事务性组件。
使用 C O M +时有五种可能的 Transaction Support属性选项:
禁止 ( D i s a b l e d )当组件的 Transaction Support属性设置为 D i s a b l e d时,C O M +将完全地忽略组件的事务要求。 C O M +首先试图在创建者的环境内激活对象。如果创建者的环境是无效的或不兼容的,C O M +在一个新的环境中激活对象。由于对象可能继承或不继承创建者的环境,则对象也就可能共享或不共享创建者的事务。
不支持 (Not Supported)当组件的 Transaction Support属性设置为 Not Supported时,组件的实例决不参与事务。这种设置是为不访问数据源的 C O M +组件设计的,其结果是组件没
562计计 ASP 3 高级编程 下载有事务开销。然而,Transaction Support属性为 Not Supported的对象总是在一个新的环境中被激活。这与 D i s a b l e d相矛盾,D i s a b l e d的对象可以共享创建者的环境。 N o t
S u p p o r t e d是缺省的 Transaction Support属性值。
支持 ( S u p p o r t e d )当组件的 Transaction Support属性设置为 S u p p o r t e d时,组件的实例参与存在的事务。但是组件对事务并没有要求,组件在事务不存在的情况下仍能很好地执行。
S u p p o r t e d属性只是表示支持事务,而不是必须要求事务存在。
需要 ( R e q u i r e d )当组件的 Transaction Support属性设置为 R e q u i r e d时,组件的实例总是在事务内执行。在激活 C O M +对象前,C O M +将使用创建者的事务 (如果存在 ),或者新的事务提供对象。不管哪种情况,组件实例总是在事务内执行。
需要新建 (Requires New)当组件的 Transaction Support属性设置为 Requires New时,总是在一个新的事务中激活组件的实例,即专为这个对象创建一个事务,而不管是否存在可用的事务。这个设置为必须在事务中完成工作,但又必须把它的工作与所有其他的事务分开的组件而设计的。使用这个设置时,C O M +对象永远不会运行在创建者的事务中。
新的事务完全独立于创建者的事务。
1,设置 Transaction Support
组件的 Transaction Support属性可以使用组件服务浏览器 (Component Services Explorer,CSE)
配置,或者在组件的类型库中指定一个缺省的 Transaction Support设置。在组件的类型库中指定一个组件的 Transaction Support属性是有益的,因为当使用 C S E从执行这项任务中解除一个管理者时,可以减少不正确地配置组件的危险。然而,记住在组件的类型库中指定的 Tr a n s a c t i o n
Support属性是一个缺省值,可以使用组件服务浏览器覆盖该值,这一点是很重要的。
在使用组件服务浏览器对一个组件的 Transaction Support属性进行配置时,简单地打开一个 C O M +应用程序的 Component Properties对话框,从 Tr a n s a c t i o n s选项卡中选择五种可能的
Transaction Support属性设置中的一个,如图 1 9 - 5所示。
图 19-5 设置 Transaction Support 的界面第 1 9章 A S P和事务性 We b应用程序 计计 563下载如果使用的是 V C + +,可以在组件类型库中为一个组件的 Transaction Support属性设置一个缺省值,可简单地通过在组件的接口定义语言 ( I D L )的定义中增加相应的一行来实现。当该组件被加到一个 C O M +的应用程序时,C O M +读取类型库并且自动地使用存储于该类型库中的
Transaction Support属性设置作为缺省值。
Visual Basic 6.0也允许开发者通过改变类模块的
M T S Tr a n s a c t i o n M o d e属性,为组件的 Tr a n s a c t i o n
S u p p o r t属性设置指定一个缺省值。不要让这个属性的名称欺骗了你,MTST ransactionMode属性不但与 M T S
一起工作,也和 C O M +一起工作。当编译一个项目时,
Visual Basic将在组件的类型库中为 Transaction Support
属性的设置放置一个等价的常量值,如图 1 9 - 6所示。
注意在 Visual Basic中 M T S Tr a n s a c t i o n M o d e值的技术术语和组件服务浏览器中的术语是不完全相同的。
然而,不必担心,除了 D i s a b l e d (对 C O M +是新的 )外,
每一个 Transaction Support属性级别都有一个对应的 M T S Tr a n s a c t i o n M o d e设置。表 1 9 - 1中列了所有可能的 M T S Tr a n s a c t i o n M o d e属性和他们的等价的 C O M + Transaction Support属性。
表 19-1 MTSTr a n s a c t i o n M o d e属性与等价的 COM+ Transaction Support属性的关系
M T S Transaction Mode属性 COM+ Transaction Support属性
0- N o t A n M T S O b j e c t Not Suppored
1- N o Tr a n s a c t i o n s Not Suppored
2- R e q u i r e s Tr a n s a c t i o n R e q u i r e d
3- U s e Tr a n s a c t i o n S u p p o r e d
4- R e q u i r e s N e w Tr a n s a c t i o n s Requires New
当组件从 Registered Components列表中加入时,因为组件服务浏览器不读取类型库,因此只要组件用 Add File对话框加到 C O M +应用程序中,就应用储存在组件的类型库中的 Transaction Support属性设置。相反地,从 Registered Components
加入的 C O M +组件,如果不用组件服务浏览器修改它们的配置,则组件使用缺省的
Transaction Support属性配置,即 Not Supported。
19.3.2 活动与同步当事务处理系统为许多用户提供服务时,能从客户中接收同时发生的调用。因此,事务处理系统必须考虑像多用户并发、同步和线程管理等问题。 C O M +能够处理这些问题,而且允许创建在多用户分布式环境中执行的组件,其创建过程同创建为单个用户服务的组件一样。
C O M +通过使用活动 ( a c t i v i t y )来完成这个惊人的任务。在 M T S中,活动是一个对象组,这些对象都在代表单个客户运行。在 C O M +中,活动是一个环境组,这些环境在代表单个客户运行,环境可能含有一个或多个对象。然而,这仅是一个微小的差别,并且可以认为环境是最内部的对象容器。
活动确保服务于同一用户的两个对象不会同时执行。在一个活动中的对象被同步以阻止在这个活动中并行地执行。活动可以由几个环境 (包含着对象 )组成,可以运行在分离的进程中,或者
564计计 ASP 3 高级编程图 19-6 设置 M T S Tr a n s a c t i o n M o d e
属性的界面下载运行在分离的机器上 (稍微有一点限制 )。由于这些原因,活动有时指的是运行的单个逻辑线程。
为什么对象的同步如此重要?考虑一个最糟糕的情况,在完全相同的时刻,代表同一用户服务的两个对象试图访问相同资源。每一个对象要完成自己的操作,就要阻塞其他对象的运行。这种情况称为死锁。活动能防止发生死锁,这是通过每次只允许一个对象代表一个用户运行来实现的。另外,活动在帮助 C O M +管理线程缓冲方面起着重要作用。
在 M T S中,活动内对象的同步是通过将活动连接到单个物理线程,或是一个 S TA实施的。
在一个活动中的对象不能并发执行,因为每个活动仅有一个物理线程。另外,C O M +使用复杂的锁定机制来确保活动中的同步。
每个活动保持着单一的独占锁。当在对象中调用一个方法并且对象的环境存在于一个活动中时,在允许处理方法调用前,C O M +首先要试图获得活动锁。如果获得锁,就由对象处理调用,直到方法调用完成,才解除锁。如果不能获得锁,就阻塞方法调用,直到获得锁才调用方法。虽然锁定过程更加复杂,但从高层次观点看,C O M +使用逻辑的活动使得多个环境和多个对象同步,基本上就是每一活动用一个单独的锁。使用锁的过程如图 1 9 - 7所示。
图 19-7 使用锁的过程环境能存在于创建者的活动或一个新的活动中或者根本没有活动。然而,单个环境不能跨越多个活动。为了建立和保持这些关系,C O M +为每个活动创建独特的用户标识符,称为
A c t i v i t y I D,存储于每个环境中。
1,创建活动和 S y n c h r o n i z a t i o n属性随着 C O M和 M T S编程模型的集成,创建活动的方法也发生了改变。使用 M T S,每个对象属于一个活动。当 V B客户使用 C r e a t e O b j e c t函数或 N e w关键字 (及某些表达式 ),或者 Vi s u a l
C + +客户使用 C o C r e a t e I n s t a n c e E X函数创建 M T S对象时,自动地创建了活动。为了在已存在的活动中创建对象,创建者必须调用 O b j e c t C o n t e x t对象中的 C r e a t e I n s t a n c e函数。
正如所想像的,这会导致大量的混乱,M T S的开发者必须意识到逻辑活动的边界,并且恰当地使用标准的对象创建技术 (CreateObject or CoCreateInstanceEX)或者 O b j e c t C o n t e x t对象的 C r e a t e I n s t a n c e函数。
使用 C O M +,仍然能自动地创建活动,但是活动的创建是通过使用组件的 S y n c h r o n i z a t i o n
属性来控制的,而不是基于如何实例化一个组件。实际上,O b j e c t C o n t e x t对象的 C r e a t e I n s t a n c e
第 1 9章 A S P和事务性 We b应用程序 计计 565下载
COM+活动
ActivityID={JMC1150-514...
Locked=True
环境
ActivityID={JMC1150-514...
环境
ActivityID={JMC1150-514...
环境
ActivityID={JMC1150-514...
ASP
函数现在的功能与标准的对象创建技术相同,并且它仅支持 M T S的向后兼容性。另外,C O M +
提供激活活动外部的对象的能力。这样可避免创建活动的额外开销和可能的调用阻塞,为频繁使用的非事务性“工具”类型的组件提升性能。如果需要,可以实现它们自己的锁定技术。
同 Transaction Support属 性 一 样
S y n c h r o n i z a t i o n属性在组件服务浏览器中的组件 P r o p e r t i e s对话框配置,如图 1 9 - 8所示。
对 S y n c h r o n i z a t i o n属性有五种可能的值:
禁止 (Disabled) 当组件的 S y n c h r o n i z a t i o n
属性设置为 D i s a b l e d时,C O M +将完全地忽 略 组 件 的 同 步 要 求 。 正 如 当
Transaction Support属性设置为 D i s a b l e d
时,C O M +将首先试图在创建者的环境中激活对象。如果创建者的环境无效或不相容,C O M +将在一个新的环境中激活对象。
如果对象继承创建者的环境,则对象可以分享创建者的活动,反之不能。应该在非事务性组件中使用这种设置,无论何时,应尽量避免创建环境和活动的额外开销。
不支持 (Not Supported) 当组件的 S y n c h r o n i z a t i o n属性设置为 Not Supported时,对象的环境将不存在于活动中。然而,S y n c h r o n i z a t i o n属性为 Not Supported的对象总是在一个新的环境中被激活。
支持 (Supported) 当组件的 S y n c h r o n i z a t i o n属性设置为 S u p p o r t e d时,对象的环境是否存在于活动中依赖于创建者的环境是否存在于活动中。然而,具有这种设置的组件不需要活动,而且在没有活动的情况也能很好地执行。
需要 (Required) 当组件的 S y n c h r o n i z a t i o n属性设置为 R e q u i r e d时,对象的环境将总是存在于活动中。如果创建者环境存在于活动中,则新的对象将在创建者的活动中激活。否则,C O M +将在位于新活动中的新环境里激活对象。
需要新建 (Requires New) 当组件的 S y n c h r o n i z a t i o n属性设置为 Requires New时,对象的环境将总是在新的活动中创建,不管创建者的环境的同步状态如何。
正如你所看到的,S y n c h r o n i z a t i o n属性的选项和 Transaction Support属性的选项非常相似。
然而,某些 S y n c h r o n i z a t i o n选项依赖于其他组件属性的某些值。特别是,支持 J I T激活的组件或 Transaction Support属性为 S u p p o r t e d,R e q u i r e d和 Requires New的组件必须在活动中被激活,
而且需要 S y n c h r o n i z a t i o n属性为 R e q u i r e d或 Requires New。只有当 J I T激活被关闭并且
Transaction Support属性设置为 D i s a b l e d或 Not Supported时,S y n c h r o n i z a t i o n属性才能设置为
D i s a b l e d或 Not Supported。我们将在下一节更多地讨论事务与活动的关系。
如果认为所有这些配置选项听起来有些令人困惑,不必担心。 M i c r o s o f t预料到这些互相依赖的配置选项会使开发者记忆混乱,他们在组件服务浏览器中建立验证功能。如果改变 J I T激活支持或者改变对 S y n c h r o n i z a t i o n属性不相容的某些 Transaction Support属性,组件服务浏览器器将用警告消息提示并自动地调整 S y n c h r o n i z a t i o n属性来反映任何变化。警告消息如图 1 9 - 9所示。
566计计 ASP 3 高级编程 下载图 19-8 配置 S y n c h r o n i z a t i o n属性的界面图 19-9 警告消息关于活动,最好的优点是它们全部通过 C O M +在幕后执行,组件不需要做任何附加工作,
C O M +提供了自动的并行和同步服务。另外,对非事务性组件提供了禁止创建活动的功能。
尽管如此,理解 S y n c h r o n i z a t i o n属性变化的作用和活动与环境在幕后如何运行是很重要的,这样才能设计出高效和可扩展的组件。现在我们对事务性 C O M +组件的可配置属性有了一定的了解,下面讨论事务的生存期的每一阶段。
19.3.3 事务的生存期
C O M +事务生存期可分为四个阶段,分别是:
事务开始。
建立并征募与 Resource Manager的连接。
在事务中执行操作。
输出事务结果并结束。
重要的是记住只有 Transaction Support属性不是 D i s a b l e d或 Not Supported时组件才需要参与事务。 C O M +组件同样能可选地表决事务的结果。
下面详细看一下在单个和多个对象的 C O M +事务中,事务生存期的每一阶段的具体情况。
1,事务开始使用 C O M +事务模型,组件不会显式地启动一个 C O M +事务。相反,C O M +在两种情况下自动地创建一个新的 C O M +事务:
Transaction Support属性为 R e q u i r e d的组件由非事务性的客户激活。
Transaction Support属性为 Requires New的组件由任何客户激活。
一个 C O M +事务由两部分组成:
逻辑事务。
物理事务。
逻辑事务也称为事务流,是共享一个物理事务的对象的一个逻辑集合或逻辑组。另一方面,物理事务是基本的 MS DTC事务,使用两阶段提交协议,根据数据源协调事务结果。当物理事务由 C O M +创建时,它使用最高级别的隔离 (可串行的 )创建,并且在组件服务浏览器中指定事务超时间隔。 C O M +从基本的物理事务中完全地抽象对象,而不是让我们通过逻辑事务流和每个对象的环境管理事务。
尽管逻辑事务可以由几个 C O M +对象组成,但是事务流 (逻辑事务 )与物理事务始终存在一一对应关系,这一点非常重要。
在事务流中创建的第一个对象,称为事务的根。事务的根能够通过实例化组件在同一事务中可选择地征募其他的 C O M +对象,这些被实例化的 C O M +组件的 Transaction Support属性为 R e q u i r e d或者 S u p p o r t e d。在这同一事务中创建对象时,C O M +自动地将根对象的环境事务第 1 9章 A S P和事务性 We b应用程序 计计 567下载信息复制到新的对象环境中,因此 C O M +能在事务中维持所有对象之间的关联。事务信息包含一个称为 Tr a n s a c t i o n I D的 G U I D值,C O M +用它识别物理 (MS DTC)事务。对象之间的关系如图 1 9 - 1 0所示。
图 19-10 对象之间的关系将被征募到创建者的事务中的新对象必须在相同的活动中创建。利用 M T S,这意味着根对象必须使用 O b j e c t C o n t e x t对象的 C r e a t e I n s t a n c e方法创建子对象。现在 C O M +已经使 M T S和
C O M编程模型成为一体,不再需要 C r e a t e I n s t a m e方法,子对象能用 Visual Basic中的
C r e a t e O b j e c t函数或 Visual C++中的 C o C r e a t e I n s t a n c e函数创建。
C O M +事务从不跨越活动,但活动与 C O M +事务不总是一一对应的关系。单个活动可能会有几个 C O M +事务。如果一个 C O M +对象实例化一个 Transaction Support属性为 Requires New
的 C O M +组件,这个新的对象将在同一活动中,但是在不同的 C O M +事务中,这个事务完全独立于创建者的事务。事务之间的关系如图 1 9 - 11所示。
图 1 9 - 11 事务之间的关系通常由 C O M +运行期自动创建物理和逻辑事务,C O M +也允许开发者在已存在的 M S
D T C (物理的 )事务中创建 C O M +对象。这个特征被恰当地称为“带着自己的事务” ( B r i n g
Your Own Tr a n s a c t i o n,B Y O T )。开发事务性组件时,这个特征给开发者提供了更多的灵活性,
同时仍然能利用 C O M +的简单性和逻辑事务模型。有了 B Y O T,组件能有效地应用 MS DTC和
C O M +编程模型的组合来虚拟地完成任何事务任务。 B Y O T的典型用途是创建具有不同属性的 MS DTC事务,例如低于可串行化的隔离级别,然后在物理事务中创建一个或更多的
C O M +组件。
2,建立与 Resource Manager的连接
568计计 ASP 3 高级编程 下载
COM+事务根子对象子对象
Required/
Supported
Requlred/
Requires New
Required/
Supported
COM+活动 事务事务
ASP
ASP
Requires New
Requires New
Requires New
创建了逻辑事务和基本的 MS DTC(物理的 )事务后,C O M +必须确保所有由 C + +对象执行的对数据源的数据修改操作在 MS DTC(物理的 )事务中执行。每个数据源的每个连接必须从征募到或注册到 MS DTC事务。
一旦这样做了,所有的操作都通过此连接执行并由 MS DTC监控。虽然对每个连接的整个征募过程由 C O M +在幕后完成,但是必须明白在事务的整个生存期中如何完成这一重要步骤的细节。
Resource Manager(RM)是数据库服务器的一部分,它使用 C O M +管理持久的数据。因此对特定的数据源的连接事实上仅是对 Resource Manager的连接。但是,C O M +事务模型在分布式的事务体系结构中增加一个软件层,称为 Resource Dispenser (RD)。
不要把 Resource Manager和 Resource Dispenser混淆,他们是在 C O M +事务模型中用于不同目的的两个不同的软件组件。
Resource Manager是一个简单的系统服务。例如数据库系统,它在分布式事务中管理着持久性资源。
MS DTC利用 Resource Manager协调事务的提交和回滚,这通过使用两阶段提交协议实现。
Resource Manager的例子包括,SQL Server,O r a c l e和 M S M Q等。
另一方面,Resource Manager是一个进程内的动态链接库,它管理存入
Resource Manager的内存中的非持久的或临时的资源。例如数据源连接、网络连接、
线程和内存数据块等。在系统出现故障时不需要保护这些共享资源。
Resource Manager能管理可再用资源的缓冲池,在事务中自动地征募或注册他们,为
C O M +对象提供针对这些资源的操作方法和接口。一个由 Resource Manager管理的最普通的非持久性资源是与控制永久性存储的底层 Resource Manager的连接。
不要让 Resource Manager这个术语迷惑了。 Resource Manager和用于访问资源的组件是一样的。例如,OLE DB服务组件总是驻留在使用 A D O或 OLE DB的客户应用程序或者对象与
OLE DB提供者及数据源之间。 C O M +指定 OLE DB服务组件作为 Resource Manager,将数据源作为 Resource Manager。其关系如图 1 9 - 1 2所示。
图 19-12 RD,R M与各个对象之间的关系前面早已提到,作为 Resource Manager,这些软件组件负责管理非持久的资源。但是它们也能可选择地提供两个重要的服务:
资源缓冲 资源缓冲是通过给 C O M +对象提供一个再循环的资源而不是创建新的资源,
提供了一个有效地分配非持久性资源的方法。 C O M +对象使用完资源后,将资源放回缓冲池中,这样它或其他的 C O M +对象可以立刻再使用这些资源。
到数据源 (Resource Manager)的连接是所使用的非持久资源中最普通的一个。创建和取消第 1 9章 A S P和事务性 We b应用程序 计计 569下载
COM+对象 ADO(OLE DB
消费者 )
OLE DB
服务组件
(RD)
OLE DB
提供者数据源
(RM)
一个到 Resource Manager的连接是一个“昂贵”的过程。为了有效地给 C O M +对象提供数据源连接,O D B C驱动程序管理器和 OLE DB服务组件都提供 Resource Manager连接的缓冲,昂贵资源的重用或循环对消耗这种资源的 C O M +对象或应用是完全透明的。
事务征募 事务征募 ( e n l i s t m e n t )是关联或征募具有 MS DTC(物理的 )事务的 R e s o u r c e
D i s p e n s e r的连接的过程。一旦完成事务征募,所有的工作由 C O M +对象通过此连接执行,
并且由 MS DTC监视并在分布式的事务中得到保护。所有的操作将作为单一的工作单元执行,事务作为一个整体需要确定其 A C I D属性。当逻辑事务完成时,MS DTC对所有参与的 Resource Manager执行两阶段提交协议。事务征募是完全可选的,R e s o u r c e
D i s p e n s e r决定是否在当前事务中征募资源。事务征募通过简化事务性 C O M +组件的开发在 C O M +事务中起着重要作用。
C O M +通过对组件隐藏分布式事务复杂的细节来完成任务。事实上,在事务生命期的此阶段中,唯一要做的是建立与数据源的连接,就像平常使用 A D O,OLE DB和 O D B C一样。
C O M +和 Resource Dispenser负责执行资源缓冲和事务征募。
3,执行操作一旦建立数据库连接,C O M +对象能依靠 Resource Manager开始执行操作。
当 Resource Manager接收和处理这些数据时,能采用相应的方法确保事务满足 A C I D要求。
许多 Resource Manager实现一个日志机制,提供回滚未提交的变化的能力,满足原子性的要求。
通过再应用或恢复未预料问题引起的变化,日志机制也允许 Resource Manager确保事务的持久性。锁用于隔离事务的变化,使其他针对同一 Resource Manager的事务不受这些变化的影响。
为确保一致性,Resource Manager通常定义特殊的机制或规则保护数据的完整性。
4,表决事务的结果前面已提到,事务性 C O M +对象的环境包含称为 Tr a n s a c t i o n I D的 G U I D值,它用于在事务中关联多个对象,并将逻辑事务链接到底层的物理事务。然而,这仅是存储在对象环境中的部分信息。事务对象的环境也包含两个其他的重要信息,它们用于完成事务,表决事务是提交还是终止。这两部分信息是:
完成标志 (Done Bit) Done Bit是个布尔值,表明对象是否应该失效,T U R E值显示对象已经完成它的工作,且可以失效,FA L S E (缺省 )值表明对象不能失效。
在方法调用完成之前,C O M +不检测 Done Bit的值。因此,Done Bit值能改变许多次,它的值在方法调用之后才有意义。 Done Bit事实上是由 J I T激活提供的,所以,可用与非事务性组件相同的方法支持 J I T激活。
一致性标志 (Consistency Bit) Consistency Bit有时称为,Happy Bit”,它是一个布尔值,
它显示 C O M +对象决定是提交还是终止事务。 T U R E值显示对象试图提交事务,FA L S E
值显示对象要强迫终止事务。
对象失效 (Done Bit设置为 T U R E )后,Consistency Bit才由 C O M +用于判断。因此,
Consistency Bit值可以重复地修改,甚至在不同的方法调用中也可以修改,因为只有对象失效前的最后值才是事务表决要用的。 C O M +用 T U R E值初始化 Consistency Bit,即 C O M +假设事务是想提交的。
Done Bit和 Consistency Bit与事务的关系如图 1 9 - 1 3所示。
570计计 ASP 3 高级编程 下载图 19-13 Done Bit和 Consistency Bit 与事务的关系当事务的根失效时 (根对象的环境的 Done Bit设置为 T U R E ),C O M +在事务流中对每个环境的 Consistency Bit赋值,来决定事务结果。试图提交事务的决定是意见一致的决定。
如果在事务中所有对象设置它们的环境的 Consistency Bit为 T U R E,表决企图提交事务,
则在事务中执行的所有操作企图进行永久性的提交。然而,如果事务中任何对象设置它的环境的 Consistency Bit为 FA L S E,表决终止事务,则在事务中完成的所有操作将被回滚。当这两种情形的任一种发生时,C O M +调用退出 MS DTC,提交或终止这个物理事务。 MS DTC然后通过使用两阶段提交协议负责与所有征募的 Resource Manager协调分布式事务的提交或终止过程。
表 1 9 - 2概述了 Done Bit和 Consistency Bit对 C O M +事务的结果的影响。
表 19-2 Done Bit和 Consistency Bit与 C O M +事务的结果的关系
Done Bit Consistency Bit C O M +事务的结果
T U R E T U R E C O M +和 MS DTC将试图提交事务
T U R E FA L S E C O M +和 MS DTC将终止事务
FA L S E T U R E 直到根对象被激活,才能提交或终止事务
FA L S E FA L S E 直到根对象被激活,才能提交或终止事务我们了解了 Done Bit和 Consistency Bit取什么值能够提交或终止 C O M +事务。下面介绍如何检索和修改它们的值。
Object Context(或 I O b j e c t C o n t e x t )接口的方法可能是编程控制 C O M +事务结果的最容易的方式,因为这种方式允许调用单个方法同时设置 Done Bit和 Consistency Bit。由于 D o n e
B i t和 Consistency Bit之间有四种可能的组合,
所以存在由 O b j e c t C o n t e x t接口定义的四个方法,它们分别是,S e t C o m p l e t e,S e t A b o r t、
E n a b l e C o m m i t和 D i s a b l e C o m m i t。
如表 1 9 - 3所示,每一个对象环境的方法与 Done Bit和 Consistency Bit值的一个独特组第 1 9章 A S P和事务性 We b应用程序 计计 571下载活动事务流环境环境环境表 19-3 ObjectContext的方法与 Done Bit和
Consistency Bit值的关系对象环境方法 Done Bit Consistency Bit
S e t C o m p l e t e T U R E T U R E
S e t A b o r t T U R E FA L S E
E n a b l e C o m m i t FA L S E T U R E
D i s a b l e C o m m i t FA L S E FA L S E
合相对应。
(1) SetComplete方法
S e t C o m p l e t e方法告诉 C O M +,一个特定的工作单元已经成功地完成。通过设置 Done Bit
和 Consistency Bit都为 T U R E,S e t C o m p l e t e方法强迫对象取消激活并表决要提交事务。只有在根对象中调用 S e t C o m p l e t e方法时,C O M +才将在每个对象的环境中检查 Consistency Bit以决定事务结果。下列代码例子展示了如何调用 S e t C o m p l e t e方法:
(2) SetAbort方法
S e t A b o r t方法告诉 C O M +,对象没有成功地完成它的工作,它想终止事务。如果一个或多个的 C O M +对象在事务中调用 S e t A b o r t方法,由于 S e t A b o r t方法设置了 Consistency Bit为
FA L S E且 Done Bit为 T U R E,整个事务将终止。
(3) EnableCommit方法
E n a b l e C o m m i t方法告诉 C O M +,对象能提交事务,但对象尚未被取消激活。 E n a b l e
C o m m i t方法通过设置 Consistency Bit为 T U R E且 Done Bit为 FA L S E完成这一任务。
572计计 ASP 3 高级编程 下载
(4) DisableCommit方法
D i s a b l e C o m m i t方法正好与 E n a b l e C o m m i t方法相反。 D i s a b l e C o m m i t方法告诉 C O M +,对象的工作没有完成,事务不能在当前提交,对象也不想取消激活。 D i s a b l e C o m m i t方法设置对象环境的 Consistency Bit和 Done Bit都为 FA L S E。由于对象仍然激活,在方法调用之间将保持其状态,
(5) 结束事务的其他方式大多数情况下,能通过 O b j e c t C o n t e x t接口显式地控制事务结果,但还有另外两种方式能结束 C O M +事务:
事务超时 ( Transaction Timeout) 如果在事务中超过事务配置的超时间隔值仍没有活动,
则结束当前事务。当一个事务超时时,它将自动地终止。默认超时间隔值是 6 0秒。在组件服务浏览器中,这个值能在组件 P r o p e r t i e s对话框的 O p t i o n s选项卡中改变。如果你正调试事务性 C O M +对象,很明显需要增加事务超时间隔,以便有足够的时间在 C O M +对象中单步调试方法调用,确保事务没有自动终止。
客户释放所有对事务根的引用 当客户释放对根对象的最后一个引用时,C O M +隐含地试图提交该事务。隐含的事务提交过程通常应该被避免,因为这会引起主机出现问题。
隐含提交的一个问题是事务的结果不会通知给客户。当根对象调用 S e t C o m p l e t e方法时,
C O M +试图在把控制返回给调用者之前提交该事务。如果提交事务时出现错误,C O M +只是简单地向客户端发送一个错误消息。这允许客户应用程序很好地处理问题并且可能再次试着进行事务处理。然而,由于隐含提交时客户端不再与根对象连接,因此如果不能提交事务,客户端就不能接收错误信息。客户完全不知道事务的结果。
隐含的事务提交过程还使得事务生存期比必要的时间长一些。当事务存在时,它保持着对资源的锁,以确保 A C I D特性的隔离要求。一个打开的、非活动的事务能阻止其他事务在这个资源上执行操作。这能引起性能瓶颈,严重限制了应用程序的可扩展性。一个更好的方法是调用 O b j e c t C o n t e x t的方法,显式地提交或终止事务。
5,事务生存期小结事务在它的生存期中经历的整个过程听起来很复杂,重要的是记住,对参与事务的
C O M +组件的唯一要求是给它们配置相应的 Transaction Support属性。有许多不同的技术为提交或终止一个事务提供了灵活性,尽管现在理解它们还有一点困难,但它们使得开发基于组件的事务性系统更容易。
19.3.4 事务访问自定义资源如何对没有提供 Resource Dispenser的资源进行事务性访问?是否需要开发一个自定义的第 1 9章 A S P和事务性 We b应用程序 计计 573下载
Resource Dispenser和 Resource Manager?如果使用 C O M +,则什么都不需要。
C O M +提供了一个新的特性,称为补偿资源管理器 (Compensating Resource Manager,
C R M ),它提供了一个基础结构来增强 C O M +对事务处理的支持能力。
Compensating Resource Manager提供了一个简单的方法,允许非事务性的资源参与由 MS DTC管理的事务。
在仍然使用 MS DTC来协调事务时,C R M是开发一个复杂的 COM+ Resource Manager和
Resource Dispenser的一个更简单的选择。例如,能开发 C R M对诸如文件系统、内存或
Windows 2000注册表等资源提供事务性访问。事务性的 C O M +组件能通过 C R M的接口访问这些资源,并且由 C R M执行的所有操作都由一个 MS DTC事务进行保护。
另外,因为使用 MS DTC作为 COM+ Resource Manager/Dispenser和 C o m p e n s a t i n g
Resource Manager的事务协调器,所以一个单一的事务可以由一些针对资源的操作组成,这些资源可以是上述的任意结构。这个特性使 Compensating Resource Manager成为能提供对资源的事务性访问的最具有吸引力的解决方案之一。
19.4 COM+事务和 I I S
M i c r o s o f t已经紧密地集成了 I I S和 C O M +的功能,这使我们能非常容易地在事务性 We b页面编程中利用事务处理应用程序。有许多不同方式集成 C O M +和 I I S的事务特性,这些例子包括:
事务性 A S P。
ASP中的 O b j e c t C o n t e x t。
事务性事件。
开发者可以在使用 I I S和 C O M +的应用程序中使用一个或多个这些特性。因为它们是紧密集成的,开发者只进行少量的工作,就能充分利用这些服务。事实上,在 C O M + 中
O b j e c t C o n t e x t封装了一个事务,可以直接用于事务中的 A S P页面。
19.4.1 事务性 A S P
由于 IIS 4.0和 M T S的集成,开发者可以在一个事务中包含 A S P脚本。这些 A S P网页可以包含对服务器组件的调用,这些组件也将参与相同的事务。同所有的事务一样,如果事务的任一部分失败,将回滚整个事务。事务性 A S P脚本所增加的优点就是使得把多个组件绑定到单个事务中变得简单化。
当处理一个终止的事务时,使用事务性脚本有一个问题。通过数据库的资源管理器访问数据库产生的改变将被自动地回滚,然而,C O M +不能回滚脚本自身产生的变化。例如,使用脚本产生的任何变化,如对 S e s s i o n或 A p p l i c a t i o n变量的改变,将不会自动地回滚。以后你将看到如何使用事务性事件通知事务已经终止。当处理这个事件时,能手工地回滚 C O M +不能自动回滚的变化。这种限制的原因是 C O M +事务只能回滚与 MS DTC相容的服务产生的变化。
在 IIS 5.0中有一个新特性。开发者具有使得一个事务跨越多个 A S P脚本网页的能力。这归功于在 S e r v e r对象上新增的 E x e c u t e和 Tr a n s f e r方法。
574计计 ASP 3 高级编程 下载然而,正常情况下,单个事务的所有处理可以在单个 A S P网页中完成。例如,如果一个应用程序有一个组件从一个帐户中提款,而另一个组件在一个帐户中存款。为了把资金从一个帐户转到另一个帐户,创建 A S P脚本,利用提款组件从帐户中取出资金,使用存款组件把资金存入新的帐户。将所有这些功能放入一个事务性 A S P网页中,如果事务过程的任一部分失败,就回滚所有的变化,帐户余额回到其初始值。
为声明一个网页是事务性的,使用下列指令:
对 T R A N S A C T I O N指令可能的设置有:
Disabled:告诉 C O M +不希望在事务中涉及组件。
Requires_New:即使已存在一个事务,也启动一个新的事务。
Required:如果不存在事务就启动一个新的,如果存在就参与到其中。
Supported:不启动一个事务,但是如果事务已经存在就参与它。
Not_Supported:即使存在事务,也不参与事务。
这些值与使用组件服务浏览器为每个组件设置的 Transaction Support属性的作用相同。
T R A N S A C T I O N指令必须处在 A S P页面脚本的第一行,通常由 L A N G U A G E指令包含。如果这之前在页面中有任何内容,将产生脚本错误。如同组件中的事务一样,如果到达代码的最后一行,还没有提交或终止,则 C O M +假定提交,并把变化写入磁盘。另外,由页面调用的每个对象能够使用同一 A S P页面的 O b j e c t C o n t e x t对象参与事务,通常就是这么做的。
19.4.2 事务性 A S P中的 O b j e c t C o n t e x t对象当编写一个事务性 A S P脚本时,你可能想直接影响脚本的事务的结果。像为事务编写的组件一样,A S P页也能利用 O b j e c t C o n t e x t对象。自从发表了 ASP 2.0以后,就可以利用这个对象,它为开发者需要的所有事务处理例程提供功能。服务器组件参与事务时访问的就是这个对象,它包含 S e t A b o r t和 S e t C o m p l e t e方法。
下列代码显示了在一个事务性 We b页中如何实例化两个 C O M对象和一个事务,并在这两个对象上调用一个方法。
注意,页面顶部的事务设置表明请求一个事务。正是该设置使该页面像 C O M组件一样参与同一事务。事实上,只要 C O M组件的 Transaction Support属性为 R e q u i r e d或 S u p p o r t e d,它们就变成由 A S P页启动的事务的一部分。
第 1 9章 A S P和事务性 We b应用程序 计计 575下载随着 A S P页执行,调用每个 C O M类的一个方法。当执行每个方法时,其返回值用于决定处理是否成功。如果任一方法返回一个非零值,A S P页调用 O b j e c t C o n t e x t对象中的 S e t A b o r t方法,回滚事务。否则,A S P页将提交事务并将变化存入磁盘。
这个例子的要点是所有的方法调用随着 A S P页面一起进入到同一事务中。
上述的例子还可以改写,使得 C O M组件中的方法从内部调用 S e t C o m p l e t e和 S e t A b o r t方法。
这将从 A S P页中删除一些逻辑,并嵌入到 C O M组件中。用这种方式编写事务的唯一问题是
A S P页不知道将要提交还是终止事务。然而,这可以通过实现事务事件来解决。
19.4.3 事务事件
A S P页也具有侦听 C O M +的能力,可以了解事务何时将提交或终止。这是通过在 C O M +提交或终止事务前 I I S调用两个例程来实现的。这两个方法称为 O n Tr a n s a c t i o n C o m m i t和
O n Tr a n s a c t i o n A b o r t。
O n Tr a n s a c t i o n C o m m i t方法在 C O M +提交事务之前、准备阶段之后被触发。只要事务中没有任何部分终止,将触发 O n Tr a n s a c t i o n C o m m i t例程 (事件 ),提交事务。如果事务被终止,则触发 O n Tr a n s a c t i o n A b o r t事件:
同大多数事务性 A S P页一样,上述例子的开始外声明它要求一个事务,接下来脚本调用一个事务性 C O M对象的方法。一旦完成该页,C O M +将通过检查是否有事务的某一部分调用了 S e t A b o r t方法来决定事务的结果。如果没有调用 S e t A b o r t方法,就触发 O n Tr a n s a c t i o n
576计计 ASP 3 高级编程 下载
C o m m i t事件,并且提交该事务;如果调用了 S a t A b o r t方法,则触发 O n Tr a n s a c t i o n A b o r t事件,
回滚事务。
19.5 用 A S P和 C O M +进行联机订购我们已经了解事务,并知道如何由 A S P进行操纵,下面举个例子。本节将以定义一个商业要求及其相关的需求开始,然后通过使用 A S P和 C O M +的事务来设计和实现。
19.5.1 业务需要在这个例子中,业务需要是订单处理系统的前端部分。订单处理系统要生成订单,同时也要调整库存数量。每次接受订单,都要正确地调整库存数量,这一点非常重要。
由于这个例子由两个任务组成 (产生订单和调整库存数量 ),将这些任务放在一个单独的事务中是必要的。这样就能利用 C O M +的功能。 C O M +能为该事务提供所有的主要工作,我们所要做的仅仅是告诉 C O M +提交或终止事务。
19.5.2 设计这个例子能分解为典型的三层结构,而且也适合 M i c r o s o f t的 D N A结构。在高层,这个例子是一个 A S P用户界面 ( U I ),在这里查看在 SQL Server 7.0数据库中的各种产品。但是,A S P
代码不与数据库交互,它利用 C O M组件从未连接的记录集窗体中检索数据。
通过 A S P用户界面检索订单,该 A S P用户界面调用一个事务性 C O M组件,这个 C O M组件把订单插入到数据库中,同时也调整库存数量。
1,数据服务如上所述,数据库将驻留于 SQL Server 7.0中。选择 SQL Server的原因是它支持 C O M +
( D T C )事务。如果需要的话,也可以使用 SQL Server 6.5。
在这个例子中有两个表,一个是产品表,另一个是订单表。为了简单起见,在称为 A S P T
r a n s a c t i o n s的数据库中使用的表名分别是 O r d e r s和 P r o d u c t s,表的结构分别如图 1 9 - 1 4和图 1 9 -
1 5所示。
图 19-14 Order表的结构应该在 P r o d u c t s表中加入一些样本数据,以便能返回到 A S P页中。
大多数应用程序建立在更复杂的数据库设计上,其数据库含有存储过程、触发器和调度的任务等。然而,作为一个示例,上述表已经足够充分了。
第 1 9章 A S P和事务性 We b应用程序 计计 577下载图 19-15 Products表的结构我们已经在本书可下载的源代码中提供了脚本,这些脚本可以创建这些数据表,
并把一些数据插入到 P r o d u c t s数据表中。
2,业务逻辑这个例子的业务逻辑将封装在一个由 V B建立的 ActiveX DLL中。该 D L L含有两个类:一个类能给调用者提供检索可用产品列表的能力,另一个类提交订单。检索产品列表的类是非事务性的,而更新列表的类是事务性的,以确保同时改变两个表。
19.5.3 实现现在打开 V B并创建新的 ActiveX DLL项目。在 V B中,设置项目的名字为 A S P Tr a n s,缺省类的名字设置为 O r d e r。增加一个类模型,称为 P r o d u c t s。
如果希望能在 O r d e r类中设置 M T S Tr a n s a c t i o n M o d e为 2- R e q u i r e s Tr a n s a c t i o n。当
O r d e r类被放入 C O M +时,它将自动地把组件的 Transaction Support属性设置为
R e q u i r e d。记住,只有从 Add File对话框把组件加入到一个 C O M +应用程序时,这种缺省设置才会生效。
在类中加入代码之前,必须首先设置正确的引用,在 R e f e r e n c e s对话框中,设置的引用为
Microsoft ActiveX Data Objects 2.5 Library和 COM+ Services Type Library,如图 1 9 - 1 6所示。
图 19-16 设置引用的界面
578计计 ASP 3 高级编程 下载现在可以把代码加到这些类中了。
1,产品组件首先在 P r o d u c t s类中增加一个名为 G e t P r o d u c t s的函数。 G e t P r o d u c t s方法没有参数,并返回一个未连接的 A D O记录集。
接着,添加所有错误处理、提交或终止事务的代码。要注意的是这个函数仅返回数据,
不更新任何资源。然而,我们仍想使用环境来通知 C O M +收回这些资源:
剩下要做的是增加一个 R e c o r d s e t对象,查找数据并返回给调用者:
第 1 9章 A S P和事务性 We b应用程序 计计 579下载新增加的代码完成了 G e t P r o d u c t s函数,它对 P r o d u c t s数据表执行一个普通的 S E L E C T语句。
注意客户端指针的使用与服务器端指针完全不同。当使用未连接的记录集工作时,必须使用客户端指针;它通知 A D O立刻获取所有的数据,而不是一次读取一点数据。一旦检索到数据,代码断开记录集,并把值返回给调用者。
2,订单组件接着,建立处理用户订单的方法。这个方法命名为 P l a c e O r d e r,是一个普通的子程序,要求有四个描述订单的参数。 P l a c e O r d e r不是一个函数,也不返回值。
P l a c e O r d e r要求的四个参数是使用者姓和名、产品的 I D和数量。 P l a c e O r d e r程序将完成两个主要的事情:在 O r d e r数据表中增加一条记录和为产品调整库存数量。
下面增加错误处理和事务支持代码。像其他的方法一样,如果出现错误,将转入
E r r o r _ H a n d l e r部分,并回滚事务;如果没有出错,将提交事务:
580计计 ASP 3 高级编程 下载现在,增加代码在 O r d e r s数据表中插入一条记录,并调整产品库存数量。这可以简单地通过创建一个 ADO Connection对象并执行一条 I N S E RT语句和一条 U P D AT E语句来完成。下面的代码可以显式地与一个 ADO Command对象一起被执行,但是为了简单起见,这个例子仅仅使用了一个 ADO Connection对象:
上述是 ActiveX DLL所需的所有代码。对这个商业逻辑来说,剩下的只是编译 D L L并将它安装到 C O M +应用程序中。
在 C O M +中安装 D L L时,记住调整 O r d e r组件中的 Transaction Support属性,以通知 C O M +
在调用时要求一个事务。在 Tr a n s a c t i o n s选项卡中,把设置调整为 R e q u i r e d,如图 1 9 - 1 7所示。
第 1 9章 A S P和事务性 We b应用程序 计计 581下载图 19-17 设置 Transaction Support属性的界面应该将 P r o d u c t s组件的 Transaction Support属性配置为 Not Supported,因为它对数据库执行只读操作。
3,用户界面在这个例子中的用户界面非常简单,由两个页面组成:一个收集用户订货信息;另一个提交订单,并通知用户其订单是否被成功地接受。
O r d e r s,a s p页向用户显示各种产品,允许他们生成一个订单。首先向该页增加一个包含订单输入控件的窗体:
582计计 ASP 3 高级编程 下载接着,增加代码调用 A c t i v e X组件和检索产品列表,这通过使用 S e r v e r对象的 C r e a t e O b j e c t
函数创建这个类的实例来完成。一旦建立了对该类实例的引用,代码就可以检索记录集,并在一个列表框中显示内容:
第 1 9章 A S P和事务性 We b应用程序 计计 583下载现在有了捕获用户输入的 A S P页面,剩下的工作是处理订单。这通过另一个称为 P l a c e
O r d e r,a s p的 A S P页面完成。 P l a c e O r d e r,a s p是一个事务性 A S P页面,它调用 ActiveX DLL中的
P l a c e O r d e r例程。 P l a c e O r d e r例程通过在数据库中增加订单记录并调整产品库存数量来更新数据库。下面开始增加 P l a c e O r d e r,a s p页面,在页面顶部设置 T R A N S A C T I O N指令,并增加
O n Tr a n s a c t i o n C o m m i t和 O n Tr a n s a c t i o n A b o r t例程:
下面,填写事务例程代码,告诉用户订单请求的结果。为了做到这一点,在例程中插入
R e s p o n s e,Wr i t e语句。
最后增加到页面的代码从 R e q u e s t对象中读取输入信息,并处理用户的订单信息。
584计计 ASP 3 高级编程 下载
19.5.4 程序验证验证一下这个例子。把一组订单增加到系统中。打开 SQL Server,观察 O r d e r s数据表中的记录,如图 1 9 - 1 8所示。
图 19-18 Orders数据表图 19-19 事务统计监视器第 1 9章 A S P和事务性 We b应用程序 计计 585下载为了验证事务处理过程,再次打开 Component Services MMC插件,并选择所要求的计算机中的 Distributed Transaction Coordinator节点下的 Transaction Statistics节点。事务统计监视器侦听 D T C提交和终止事务,并且显示汇总结果,如图 1 9 - 1 9所示。
19.6 小结本章阐述了事务处理的概念以及如何在 I I S应用程序中通过使用 Windows 2000的组件服务
( C O M + )来操纵事务。
M i c r o s o f t已经为开发者提供了一系列强有力的服务,应用程序可以使用这些服务创建。
这些服务,例如事务处理 ( D T C ),允许开发者集中精力解决业务问题,而不必担心服务之间的底层通信。
本章主要介绍了:
事务处理的定义。
事务的目的。
在 C O M +中如何进行事务处理。
组件中的事务。
ASP中的事务。
下一章将讨论 C O M +提供的另一个服务:消息排队。
586计计 ASP 3 高级编程 下载