Active Server Pages(ASP)是Microsoft公司推出的Windows NT环境下服务器端的脚本编写语言,利用它可以调用Web服务器上注册的ActiveX组件来执行任务,从而生成功能强大的Web应用程序。由于ASP脚本在Web服务器上运行,用ASP创建的应用可以被跨不同平台运行的多种Web浏览器访问。
在IIS 4.0中,ASP结构提供了六个内建对象, 内建对象的特殊性在于,它们在 ASP 页内生成且在脚本中使用它们前无须创建。其中,内建对象ObjectContext专门用于支持开发基于Microsoft Transaction Server(MTS)的事务型Web应用软件。
一、ASP的内建对象
ASP的六个内建对象介绍如下:
(1)Application 对象
可以使用Application对象在Web应用程序的所有用户之间共享信息。基于 ASP 的Web应用程序在一个虚拟目录及其子目录中定义。因为多个用户可以共享 Application 对象,所以必须要用 Lock 和 Unlock 方法以确保多个用户无法同时改变某一属性。
(2)ObjectContext 对象
可以使用 ObjectContext 对象提交或放弃一项由MTS管理的事务。具体细节,后面将加以详述。
(3)Request 对象
使用Request 对象可以获得客户端浏览器传递给Web服务器的参数值 。
(4)Response 对象
使用 Response 对象可以将输出发送到客户端。
(5)Server 对象
Server 对象的CreateObject方法可以在服务器端创建一个ActiveX组件的实例,从而使用ActiveX组件来执行任务,例如对数据库操作等。
(6)Session 对象
可以使用 Session 对象存储特定用户会话所需的信息。这样,当用户在应用程序的 Web 页之间跳转时,存储在 Session 对象中的变量将不会丢失,而是在整个用户会话中一直存在下去。当用户请求应用程序的 Web 页时,如果该用户还没有会话,则 Web 服务器将自动创建一个 Session 对象。当会话过期或被放弃后,服务器将终止该会话。
二、ASP事务处理基本原理
ASP 事务处理是以Microsoft Transaction Server(简称MTS)为基础的。MTS 是一个运行于Windows NT环境下的事务处理系统,用于开发、配置和管理高性能、可分级的、有鲁棒性的企业 Internet 和 Intranet 服务器应用程序。MTS为开发分布式的,基于组件的应用程序提供了一个应用程序设计模型,它也为配置和管理这些应用程序提供了一个运行环境。
创建事务性脚本的功能内置在 Internet Information Server中。如果您安装了 Microsoft Transaction Server,就可以将组件打包,以使组件在事务内部运行。
事务是整体成功或失败的操作,事务处理常用于对数据库进行可靠地更新。在对数据库进行许多相关更改或同时更新多个数据库时,要保证所有更改都被正确执行。如果这些更改中的任何一个失败,都需要恢复数据库表的原始状态。
如果没有 MTS,您就需要编写脚本和组件,手工跟踪请求的更改情况,以便在某些更改失败时恢复数据。使用 MTS,您只需简单的将您的脚本和组件声明为“需要事务”并让 MTS 处理事务的一致性。事务处理只适用于数据库访问;MTS 不能对文件系统或其他的非事务性资源的更改进行恢复操作。应用程序所访问的数据库必须为 MTS 所支持。目前,MTS 支持 Microsoft SQL Server 及任何支持 XA 协议(由 X/Open 协会制定)的服务器。MTS 将继续扩展对其他数据库的支持。
事务不能跨越多个 ASP 页。如果一个事务需要来自多个组件的对象,则须将使用这些对象的操作组合在一个 ASP 页中。例如,假定有一个组件用于更新工资单数据库,还有一个组件用于更新人力资源数据库中的员工记录。为了记录一个员工的新的工资信息,您需要编写这样一个脚本,该脚本在一个事务环境中调用这两个组件,一个用于更新工资单数据库,另一个用于更新人力资源数据库中的员工等级。
三、在ASP脚本中编写事务型应用
1. 声明事务性脚本
在将一个ASP页声明为事务性时,此页中的任何脚本命令和对象都运行在同一个事务环境中,MTS处理生成事务的细节并决定事务成功(提交)或失败(终止)。要将某个页声明为事务性,可在页首添加 @TRANSACTION 指令:
〈%@ TRANSACTION = value %〉
value 参数可以是下列之一:
Requires_New :启动一个新的事务。
Required : 启动一个新的事务。
Supported: 不启动事务。
Not_Supported: 不启动事务。
@TRANSACTION 指令必须在一页中的第一行,否则将产生错误。必须将该指令添加到需要在事务下运行的每一页中。当脚本处理结束时,当前事务即告结束。
如果事务被终止,MTS将恢复对支持事务的资源的任何更改。目前,仅数据库服务器完全支持事务,因为数据库中的数据对于企业应用是最为关键的。MTS不对硬盘上的文件、会话和应用程序的变量、集合等的改变进行恢复,然而您可以如下文所述,通过编写事务事件来编写恢复变量和集合的脚本。在某些时候,您的脚本也可以显式的提交或终止一个事务,如向文件写数据失败时。
2. 提交或终止脚本
利用 ObjectContext 对象可以提交或放弃一项由MTS管理的事务,为此,ObjectContext 对象提供了两个方法:
(1)SetComplete 方法
声明脚本不了解事务未完成的原因。如果事务中的所有组件都调用 SetComplete,事务将完成。
(2)SetAbort 方法
声明被脚本初始化的事务未完成,无法更新源。
示例:
这里示范使用 SetAbort 和SetComplete 的方法。假设有一个网上有偿借阅图书馆的主页,其中,BorrowBookData.htm 文件获取处理借阅图书请求所需的数据。第二个文件BorrowVerify.asp 中的脚本使用两个对象Inventory 和 Borrow 来处理借阅(注意,在本文所举的例子中,使用了一些作者自己开发的Web服务器端ActiveX组件对象,如对象Inventory 和 Borrow等,在实际应用中,这些组件对象需由读者自行开发)。如果 Inventory 返回了错误代码表示存书不足,就会调用 SetAbort。如果 Inventory 对象没有返回错误代码,将会调用 SetComplete 处理借阅请求。
BorrowBookData.htm 源文件:
〈HTML〉
〈HEAD〉
〈TITLE〉借书单〈/TITLE〉
〈/HEAD〉
〈BODY〉
〈H2〉借书单〈/H2〉
〈FORM METHOD="POST" ACTION="Borrow Verify.asp"〉
请输入书号、借阅数量、借阅费用:
〈INPUT TYPE="TEXT" NAME="Book Code" 〉
〈INPUT TYPE="TEXT" NAME="QuantityTo Borrow" 〉
〈INPUT TYPE="TEXT" NAME="Account In" 〉
〈INPUT TYPE="SUBMIT" VALUE="提交" 〉
〈/FORM〉
〈/BODY〉
〈/HTML〉
BorrowVerify.asp源文件:
〈%@ Transaction = Required %〉
〈%
Set CurrentQOB = Server.CreateObject("Mylib. Inventory") ' 创建Inventory对象
Set CurrentBorrow = Server.CreateObject ("Mylib.Borrow") ' 创建Borrow对象
CheckQuantity = Request.Form("QuantityTo Borrow")
CheckBook = Request.Form("BookCode")
QuantityStatus = CurrentQOB.CheckQOB (CheckQuantity,CheckBook) '检查存书量
If QuantityStatus = None '如果存书量不足
ObjectContext.SetAbort '终止事务
Response.Write "对不起,存书量不足!"
Else '如果存书量充足
ObjectContext.SetComplete '继续执行事务
Account = Request.Form("AccountIn")
Saleupdate = CurrentBorrow.PostIt(Account)
End If
%〉
3. 编写事务事件
脚本本身不能决定事务是成功还是失败。但是,可以编写提交或终止事务时被调用的事件。为此,ObjectContext 对象提供了两个事件:
(1)OnTransactionCommit 事件
它在一个已处理的脚本事务提交后发生。该事件发生时,如果脚本中有 OnTransactionCommit 子例程,IIS 将处理该子例程。
(2)OnTransactionAbort 事件
如果事务异常终止,就会发生该事件。当 OnTransactionAbort 事件发生时,如果脚本中有 OnTransactionAbort 子程序,则 IIS 将执行它。
例如,假设有一个根据借阅者帐户、密码进行业务处理的脚本,并且您需要针对事务的不同状态将不同的页返回给用户,那么就可以使用 OnTransactionCommit 和 OnTransactionAbort 事件来编写对用户的不同响应。
示例:
〈%@ TRANSACTION = Required %〉
〈%Response.Buffer = True '缓存输出 %〉
〈HTML〉
〈BODY〉
〈H1〉网上有偿借阅图书馆〈/H1〉
〈% ' 创建作者自己开发的ActiveX组件对象
Set LibAction = Server.CreateObject ("MyExample.LibComponent")
' 根据借阅者输入的帐户、密码进行业务处理
LibAction.Borrow(Request.Form("Account Num"),Request.Form("Password"))
%〉
〈/BODY〉
〈/HTML〉
〈% ' 如果借阅者帐户有效显示下页
Sub OnTransactionCommit()
Response.Write "〈HTML〉"
Response.Write "〈BODY〉"
Response.Write "帐户有效!"
Response.Write "〈/BODY〉"
Response.Write "〈/HTML〉"
Response.Flush()
End sub %〉
〈% ' 如果借阅者帐户无效显示下页
Sub OnTransactionAbort()
Response.Clear()
Response.Write "〈HTML〉"
Response.Write "〈BODY〉"
Response.Write "帐户无效!"
Response.Write "〈/BODY〉"
Response.Write "〈/HTML〉"
Response.Flush()
End sub %〉
if ($ != jQuery) { $ = jQuery.noConflict(); }