商業應用程序常常需要具有在事務內部運行腳本和組件的能力。事務是一種服務器操作,即使該操作包括很多步驟(例如,定貨、查看存貨、付帳等),也只能整體返回操作是成功還是失敗。用戶可以創建在事務內部運行的 ASP 腳本,如果腳本的任何一部分失敗,整個事務都將會終止。
ASP 事務處理是以 Microsoft® Transaction Server (MTS) 為基礎的。Microsoft® Transaction Server (MTS) 是一個事務處理系統,用於開發、配置和管理高性能、可分級的、有魯棒性的企業 Internet 和 Intranet 服務器應用程序。Transaction Server 為開發分布式的,基於組件的應用程序提供了一個應用程序設計模型。它也為配置和管理這些應用程序提供了一個運行環境。
創建事務性腳本的功能內置在 Internet Information Server 和 Personal Web Server 中。如果您安裝了 Microsoft Transaction Server,就可以將組件打包,以使組件在事務內部運行。
關於事務
事務是整體成功或失敗的操作。事務處理用於對數據庫進行可靠地更新。在對數據庫進行許多相關更改或同時更新多個數據庫時,要保證所有更改都被正確執行。如果這些更改中的任何一個失敗,都需要恢復數據庫表的原始狀態。
如果沒有 MTS,您就需要編寫腳本和組件,手工跟蹤請求的更改情況,以便在某些更改失敗時恢復數據。使用 MTS,您只需簡單的將您的腳本和組件聲明為“需要事務”並讓 MTS 處理事務的一致性。事務處理只適用於數據庫訪問;MTS 不能對文件系統或其他的非事務性資源的更改進行恢復操作。應用程序所訪問的數據庫必須為 MTS 所支持。目前,MTS 支持 SQL Server 及任何支持 XA 協議(由 X/Open 協會制定)的服務器。MTS 將繼續擴展對其他數據庫的支持。
事務不能跨越多個 ASP 頁。如果一個事務需要來自多個組件的對象,則須將使用這些對象的操作組合在一個 ASP 頁中。例如,假定有一個組件用於更新工資單數據庫,還有一個組件用於更新人力資源數據庫中的員工記錄。為了記錄一個員工的新的工資信息,您需要編寫這樣一個腳本,該腳本在一個事務環境中調用這兩個組件,一個用於更新工資單數據庫,另一個用於更新人力資源數據庫中的員工等級。
聲明事務性腳本
在將一個頁聲明為事務性時,此頁中的任何腳本命令和對象都運行在同一個事務環境中。Transaction Server 處理生成事務的細節並決定事務成功(提交)或失敗(終止)。要將某個頁聲明為事務性,可在頁首添加 @TRANSACTION 指令:
<%@ TRANSACTION = value %>
value 參數可以是下列之一:
值 意義
Requires_New 啟動一個新的事務。
Required 啟動一個新的事務。
Supported 不啟動事務。
Not_Supported 不啟動事務。
@TRANSACTION 指令必須在一頁中的第一行,否則將產生錯誤。必須將該指令添加到需要在事務下運行的每一頁中。當腳本處理結束時,當前事務即告結束。
大多數應用程序只有一些特定的操作需要事務環境。例如,一個航空公司的站點可能只需要事務性腳本處理購票和安排座位,而其他所有腳本則無須事務環境即可安全運行。因為事務只須用於需要事務處理的頁即可,不要將應用程序的 Global.asa 文件聲明為事務性。
如果事務被終止,Transaction Server 將恢復對支持事務的資源的任何更改。目前,僅數據庫服務器完全支持事務,因為數據庫中的數據對於企業應用是最為關鍵的。Transaction Server 不對硬盤上的文件、會話和應用程序的變量、集合等的改變進行恢復。然而您可以如下文主題所述,通過編寫事務事件來編寫恢復變量和集合的腳本。在某些時候,您的腳本也可以顯式的提交或終止一個事務,如向文件寫數據失敗時。
提交或終止腳本
因為 Transaction Server 跟蹤事務處理,所以它決定事務是完全成功還是失敗。腳本可以通過調用 ObjectContext.SetAbort 顯式地聲明終止一個事務。 例如,當一個事務在從一個組件收到錯誤消息、違反商業規范時(例如,帳戶余額小於 0)或讀寫文件等非事務性操作失敗時,腳本就需要終止該事務。如果頁在事務完成之前超時,也必須終止事務。
編寫事務事件
腳本本身不能決定事務是成功還是失敗。但是,可以編寫提交或終止事務時被調用的事件。例如,假設有一個確認銀行帳戶的腳本,並且您需要針對事務的不同狀態將不同的頁返回給用戶,那麼就可以使用 OnTransactionCommit 和 OnTransactionAbort 事件來編寫對用戶的不同響應。
<%@ TRANSACTION = Required %>
<%
'Buffer output so that different pages can be displayed.
Response.Buffer = True
%>
<Html>
<BODY>
<H1>Welcome to the online banking service</H1>
<%
Set BankAction = Server.CreateObject("MyExample.BankComponent")
BankAction.Deposit(Request("AcctNum"))
%>
<P>Thank you. Your transaction is being PRocessed.</P>
</BODY>
</Html>
<%
' Display this page if the transaction succeeds.
Sub OnTransactionCommit()
Response.Write "<Html>"
Response.Write "<BODY>"
Response.Write "Thank you. Your account has been credited."
Response.Write "</BODY>"
Response.Write "</Html>"
Response.Flush()
end sub
%>
<%
' Display this page if the transaction fails.
Sub OnTransactionAbort()
Response.Clear()
Response.Write "<Html>"
Response.Write "<BODY>"
Response.Write "We are unable to complete your transaction."
Response.Write "</BODY>"
Response.Write "</Html>"
Response.Flush()
End sub
%>
在 MTS 資源管理器中登記一個組件
為了參與一個事務,組件必須在 MTS 包中登記,而且必須被配置為需要事務。例如,如果您的腳本是通過調用兩個組件來處理訂單的,一個更新庫存數據庫,另一個更新付款數據庫。那麼,這兩個組件就要在同一個事務環境中運行。Transaction Server 保證如果任意一個組件失敗,那麼將不會有數據庫被更新。某些組件不需要事務;例如,Ad Rotator 組件。
注冊和配置事務性組件可使用 MTS 資源管理器。必須將事務的屬性設置為需要事務或需要新事務。事務組件必須在 MTS 包中注冊。不要將組件放在 IIS 內部進程包中,而應該創建自己的包。通常,應將所有的組件放在一個組件庫中。組件庫的組件可被多個 ASP 應用程序使用並以 ASP 應用程序進程運行。使用 MTS 資源管理器可創建新的包並將包的 Activation 屬性設置為 Library。
也可以在 Server 包中注冊事務性組件。Server 包通常以服務器上的一個獨立的進程運行。如果希望使用基於職能組的安全性檢查或希望您的組件可被遠程計算機上的應用程序訪問,可對事務性組件使用 Server 包。
要使用 MTS 資源管理器,必須安裝 Microsoft Transaction Server。
對象作用域
一般情況下,不要將從 MTS 組件中創建的對象存儲在 ASP application 或 session 對象中。 MTS 對象在事務完成後消失。因為 Session 對象和 Application 對象是為在不同 ASP 頁之間使用的對象實例設計的,所以不要用它們保存在事務結束時即被釋放的對象。
ASP 腳本是已聲名的事務的根,即起始點。任何事務性 ASP 頁所使用的 MTS 對象都被認為是事務的一部分。當事務完成後,在頁中使用的 MTS 對象將消失,其中包括存儲在 Session 或 Application 對象中的對象。在此之後,從另一個事務性頁中調用會話作用域或應用程序作用域對象的嘗試都將失敗。
事務排隊
從一個遠程服務器對數據庫的更新可能因為網絡延遲或故障而導致事務延遲或終止。因為事務的所有部分都必須提交,所以應用程序將可能掛起,等待遠程服務器的提交或終止消息,也可能由於無法發送數據庫更新而導致事務被放棄。
對於必須同時完成的更新,正確的做法是在事務的所有參與者都能夠提交之前,終止事務或推遲完成事務。例如,航空公司的定票程序應該同時完成對客戶的銀行帳號計入借方和對航空公司的銀行帳戶計入貸方。如果一個更新屬於事務整體的一部分,但可能晚於其他更新,您可能不希望讓客戶等待整個更新過程的完成。例如,機票預定事務可能也要向食品供應商發送食品訂單或更新客戶的旅程津貼。這些操作雖然也必須完成,但可以晚一些。
Microsoft Message Queue Server 使您能夠將一個或一組更新捆綁到一個事務性消息中送給遠程服務器。Message Queue Server 保證更新將被發送給遠程服務器,即使目前網絡不可用。您的應用將收到一個提交消息,從而可以繼續處理事務。