ASP中事务处理资料收集
生活随笔
收集整理的這篇文章主要介紹了
ASP中事务处理资料收集
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
在IIS ? 中,ASP結(jié)構(gòu)提供了六個(gè)內(nèi)建對(duì)象, ? 內(nèi)建對(duì)象的特殊性在于,它們?cè)?? ASP ? 頁(yè)內(nèi)生成且在腳本中使用它們前無須創(chuàng)建。其中,內(nèi)建對(duì)象ObjectContext專門用于支持開發(fā)基于Microsoft ? Transaction ? Server(MTS)的事務(wù)型Web應(yīng)用軟件。 ? ?
? 1.ASP事務(wù)處理基本原理 ? ?
? ASP ? 事務(wù)處理是以Microsoft ? Transaction ? Server(簡(jiǎn)稱MTS)為基礎(chǔ)的。MTS ? 是一個(gè)運(yùn)行于Windows ? NT環(huán)境下的事務(wù)處理系統(tǒng),用于開發(fā)、配置和管理高性能、可分級(jí)的、有魯棒性的企業(yè) ? Internet ? 和 ? Intranet ? 服務(wù)器應(yīng)用程序。MTS為開發(fā)分布式的,基于組件的應(yīng)用程序提供了一個(gè)應(yīng)用程序設(shè)計(jì)模型,它也為配置和管理這些應(yīng)用程序提供了一個(gè)運(yùn)行環(huán)境。 ? ?
? 創(chuàng)建事務(wù)性腳本的功能內(nèi)置在 ? Internet ? Information ? Server中。如果您安裝了 ? Microsoft ? Transaction ? Server,就可以將組件打包,以使組件在事務(wù)內(nèi)部運(yùn)行。 ? ?
? 事務(wù)是整體成功或失敗的操作,事務(wù)處理常用于對(duì)數(shù)據(jù)庫(kù)進(jìn)行可靠地更新。在對(duì)數(shù)據(jù)庫(kù)進(jìn)行許多相關(guān)更改或同時(shí)更新多個(gè)數(shù)據(jù)庫(kù)時(shí),要保證所有更改都被正確執(zhí)行。如果這些更改中的任何一個(gè)失敗,都需要恢復(fù)數(shù)據(jù)庫(kù)表的原始狀態(tài)。 ? ?
? 如果沒有 ? MTS,您就需要編寫腳本和組件,手工跟蹤請(qǐng)求的更改情況,以便在某些更改失敗時(shí)恢復(fù)數(shù)據(jù)。使用 ? MTS,您只需簡(jiǎn)單的將您的腳本和組件聲明為“需要事務(wù)”并讓 ? MTS ? 處理事務(wù)的一致性。事務(wù)處理只適用于數(shù)據(jù)庫(kù)訪問;MTS ? 不能對(duì)文件系統(tǒng)或其他的非事務(wù)性資源的更改進(jìn)行恢復(fù)操作。應(yīng)用程序所訪問的數(shù)據(jù)庫(kù)必須為 ? MTS ? 所支持。目前,MTS ? 支持 ? Microsoft ? SQL ? Server ? 及任何支持 ? XA ? 協(xié)議(由 ? X/Open ? 協(xié)會(huì)制定)的服務(wù)器。MTS ? 將繼續(xù)擴(kuò)展對(duì)其他數(shù)據(jù)庫(kù)的支持。 ? ?
? 事務(wù)不能跨越多個(gè) ? ASP ? 頁(yè)。如果一個(gè)事務(wù)需要來自多個(gè)組件的對(duì)象,則須將使用這些對(duì)象的操作組合在一個(gè) ? ASP ? 頁(yè)中。例如,假定有一個(gè)組件用于更新工資單數(shù)據(jù)庫(kù),還有一個(gè)組件用于更新人力資源數(shù)據(jù)庫(kù)中的員工記錄。為了記錄一個(gè)員工的新的工資信息,您需要編寫這樣一個(gè)腳本,該腳本在一個(gè)事務(wù)環(huán)境中調(diào)用這兩個(gè)組件,一個(gè)用于更新工資單數(shù)據(jù)庫(kù),另一個(gè)用于更新人力資源數(shù)據(jù)庫(kù)中的員工等級(jí)。 ? ?
? ?
? 2.在ASP腳本中編寫事務(wù)型應(yīng)用 ? ?
? 1. ? 聲明事務(wù)性腳本 ? ?
? 在將一個(gè)ASP頁(yè)聲明為事務(wù)性時(shí),此頁(yè)中的任何腳本命令和對(duì)象都運(yùn)行在同一個(gè)事務(wù)環(huán)境中,MTS處理生成事務(wù)的細(xì)節(jié)并決定事務(wù)成功(提交)或失敗(終止)。要將某個(gè)頁(yè)聲明為事務(wù)性,可在頁(yè)首添加 ? @TRANSACTION ? 指令: ? ?
? ?
? value ? 參數(shù)可以是下列之一: ? ?
? Requires_New ? :啟動(dòng)一個(gè)新的事務(wù)。 ? ?
? Required ? : ? 啟動(dòng)一個(gè)新的事務(wù)。 ? ?
? Supported: ? 不啟動(dòng)事務(wù)。 ? ?
? Not_Supported: ? 不啟動(dòng)事務(wù)。 ? ?
? @TRANSACTION ? 指令必須在一頁(yè)中的第一行,否則將產(chǎn)生錯(cuò)誤。必須將該指令添加到需要在事務(wù)下運(yùn)行的每一頁(yè)中。當(dāng)腳本處理結(jié)束時(shí),當(dāng)前事務(wù)即告結(jié)束。 ? ?
? 如果事務(wù)被終止,MTS將恢復(fù)對(duì)支持事務(wù)的資源的任何更改。目前,僅數(shù)據(jù)庫(kù)服務(wù)器完全支持事務(wù),因?yàn)閿?shù)據(jù)庫(kù)中的數(shù)據(jù)對(duì)于企業(yè)應(yīng)用是最為關(guān)鍵的。MTS不對(duì)硬盤上的文件、會(huì)話和應(yīng)用程序的變量、集合等的改變進(jìn)行恢復(fù),然而您可以如下文所述,通過編寫事務(wù)事件來編寫恢復(fù)變量和集合的腳本。在某些時(shí)候,您的腳本也可以顯式的提交或終止一個(gè)事務(wù),如向文件寫數(shù)據(jù)失敗時(shí)。 ? ?
? 2. ? 提交或終止腳本 ? ?
? 利用 ? ObjectContext ? 對(duì)象可以提交或放棄一項(xiàng)由MTS管理的事務(wù),為此,ObjectContext ? 對(duì)象提供了兩個(gè)方法: ? ?
? (1)SetComplete ? 方法 ? ?
? 聲明腳本不了解事務(wù)未完成的原因。如果事務(wù)中的所有組件都調(diào)用 ? SetComplete,事務(wù)將完成。 ? ?
? (2)SetAbort ? 方法 ? ?
? 聲明被腳本初始化的事務(wù)未完成,無法更新源。 ? ?
? 示例: ? ?
? <%@ ? Transaction ? = ? Required ? %> ?
? <% ?
? Set ? CurrentQOB ? = ? Server.CreateObject("Mylib. ? Inventory") ? ' ? 創(chuàng)建Inventory對(duì)象 ?
? Set ? CurrentBorrow ? = ? Server.CreateObject ? ("Mylib.Borrow") ? ' ? 創(chuàng)建Borrow對(duì)象 ?
? CheckQuantity ? = ? Request.Form("QuantityTo ? Borrow") ?
? CheckBook ? = ? Request.Form("BookCode") ?
? QuantityStatus ? = ? CurrentQOB.CheckQOB ? (CheckQuantity,CheckBook)'檢查存書量 ?
? If ? QuantityStatus ? = ? None ? '如果存書量不足 ?
? ObjectContext.SetAbort ? '終止事務(wù) ?
? Response.Write ? "對(duì)不起,存書量不足!" ?
? Else'如果存書量充足 ?
? ObjectContext.SetComplete ? '繼續(xù)執(zhí)行事務(wù) ?
? Account ? = ? Request.Form("AccountIn") ?
? Saleupdate ? = ? CurrentBorrow.PostIt(Account) ?
? End ? If ?
? %> ?
? ?
? ?
? 這里示范使用 ? SetAbort ? 和SetComplete ? 的方法。假設(shè)有一個(gè)網(wǎng)上有償借閱圖書館的主頁(yè),其中,BorrowBookData.htm ? 文件獲取處理借閱圖書請(qǐng)求所需的數(shù)據(jù)。第二個(gè)文件BorrowVerify.asp ? 中的腳本使用兩個(gè)對(duì)象Inventory ? 和 ? Borrow ? 來處理借閱(注意,在本文所舉的例子中,使用了一些作者自己開發(fā)的Web服務(wù)器端ActiveX組件對(duì)象,如對(duì)象Inventory ? 和 ? Borrow等,在實(shí)際應(yīng)用中,這些組件對(duì)象需由讀者自行開發(fā))。如果 ? Inventory ? 返回了錯(cuò)誤代碼表示存書不足,就會(huì)調(diào)用 ? SetAbort。如果 ? Inventory ? 對(duì)象沒有返回錯(cuò)誤代碼,將會(huì)調(diào)用 ? SetComplete ? 處理借閱請(qǐng)求。 ? ?
? BorrowBookData.htm ? 源文件: ? ?
? ?
? ?
? <%@ ? TRANSACTION ? = ? Required ? %> ?
? <%Response.Buffer ? = ? True ? '緩存輸出 ? %> ?
? <HTML> ?
? <BODY> ?
? <H1>網(wǎng)上有償借閱圖書館</H1> ?
? <% ? ' ? 創(chuàng)建作者自己開發(fā)的ActiveX組件對(duì)象 ?
? Set ? LibAction ? = ? Server.CreateObject ? ("MyExample.LibComponent") ?
? ' ? 根據(jù)借閱者輸入的帳戶、密碼進(jìn)行業(yè)務(wù)處理 ?
? LibAction.Borrow(Request.Form("Account ? Num"),Request.Form("Password")) ?
? %> ?
? </BODY> ?
? </HTML> ?
? <% ? ' ? 如果借閱者帳戶有效顯示下頁(yè) ?
? Sub ? OnTransactionCommit() ?
? Response.Write ? "<HTML>" ?
? Response.Write ? "<BODY>" ?
? Response.Write ? "帳戶有效!" ?
? Response.Write ? "</BODY>" ?
? Response.Write ? "</HTML>" ?
? Response.Flush() ?
? End ? sub ? %> ?
? <% ? ' ? 如果借閱者帳戶無效顯示下頁(yè) ?
? Sub ? OnTransactionAbort() ?
? Response.Clear() ?
? Response.Write ? "<HTML>" ?
? Response.Write ? "<BODY>" ?
? Response.Write ? "帳戶無效!" ?
? Response.Write ? "</BODY>" ?
? Response.Write ? "</HTML>" ?
? Response.Flush() ?
? End ? sub ? %> ?
? ?
? ?
? 3. ? 編寫事務(wù)事件 ? ?
? 腳本本身不能決定事務(wù)是成功還是失敗。但是,可以編寫提交或終止事務(wù)時(shí)被調(diào)用的事件。為此,ObjectContext ? 對(duì)象提供了兩個(gè)事件: ? ?
? (1)OnTransactionCommit ? 事件 ? ?
? 它在一個(gè)已處理的腳本事務(wù)提交后發(fā)生。該事件發(fā)生時(shí),如果腳本中有 ? OnTransactionCommit ? 子例程,IIS ? 將處理該子例程。 ? ?
? (2)OnTransactionAbort ? 事件 ? ?
? 如果事務(wù)異常終止,就會(huì)發(fā)生該事件。當(dāng) ? OnTransactionAbort ? 事件發(fā)生時(shí),如果腳本中有 ? OnTransactionAbort ? 子程序,則 ? IIS ? 將執(zhí)行它。 ? ?
? 例如,假設(shè)有一個(gè)根據(jù)借閱者帳戶、密碼進(jìn)行業(yè)務(wù)處理的腳本,并且您需要針對(duì)事務(wù)的不同狀態(tài)將不同的頁(yè)返回給用戶,那么就可以使用 ? OnTransactionCommit ? 和 ? OnTransactionAbort ? 事件來編寫對(duì)用戶的不同響應(yīng)。?
_______________________
-------------------------------------------------------------------------------- ?
? ? 運(yùn)氣 ? 于 ? 8/24/2001 ? 9:46:19 ? AM ? 加貼在 ? Joy ? ASP ? ←返回版面: ? ? ? ?
? 在開發(fā)Web應(yīng)用時(shí),無一例外地需要訪問數(shù)據(jù)庫(kù),以完成對(duì)數(shù)據(jù)的查詢、插入、更新、刪除等操作。受應(yīng)用邏輯的影響,有時(shí)需要將多條數(shù)據(jù)庫(kù)操作指令組成一個(gè)工作單元(事務(wù))。在數(shù)據(jù)庫(kù)中,所謂事務(wù)是指一組邏輯操作單元,它使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)。為確保數(shù)據(jù)庫(kù)中數(shù)據(jù)的一致性,應(yīng)當(dāng)用離散的成組的邏輯單元操作數(shù)據(jù):當(dāng)它全部完成時(shí),數(shù)據(jù)的一致性可以保持;而當(dāng)單元中的一部分操作失敗時(shí),整個(gè)事務(wù)會(huì)被全部忽略,所有從起始點(diǎn)以后的操作全部退回到開始狀態(tài)。 ? ?
? 實(shí)際上,在默認(rèn)方式下對(duì)數(shù)據(jù)庫(kù)的每一次操作都是隱含的事務(wù)處理。本文以一個(gè)典型的用戶注冊(cè)程序?yàn)槔?#xff0c;介紹三種利用ASP實(shí)現(xiàn)事務(wù)處理的方法:基于ASP數(shù)據(jù)庫(kù)組件的解決方法、基于數(shù)據(jù)庫(kù)內(nèi)部的事務(wù)處理機(jī)制的解決方法和基于MTS組件的解決方法。 ? ?
? ?
? 程序功能 ? ?
? 在SQL ? Server數(shù)據(jù)庫(kù)中建立兩個(gè)表:USER表和USERDOC表。其中USER表中存放的是注冊(cè)用戶的用戶名和密碼,USERDOC表中存放的是該注冊(cè)用戶的個(gè)人資料,并且以用戶名為索引。下面是表USER和USERDOC的定義: ? ?
? Create ? Table ? USER(userName ? varchar(30),userPasswd ? varchar(30)) ? ?
? Create ? Table ? USERDOC(userName ? varchar(30),Age ? int,Sex ? int,PhoneNumber ? varchar(20),Address ? varchar(50)) ? ?
? 當(dāng)用戶請(qǐng)求注冊(cè)時(shí),ASP腳本先將用戶名和密碼插入到USER表中,然后在USERDOC表中插入用戶個(gè)人信息(年齡、性別、聯(lián)系電話和家庭住址等)。同時(shí),應(yīng)用程序還必須保證USER表中的每一條記錄在USERDOC表中都有相應(yīng)的記錄。 ? ?
? 方法一 ? ?
? 利用ASP內(nèi)置ADO組件中的Connection對(duì)象可以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)操作的事務(wù)性處理。Connection對(duì)象的部分方法如下: ? ?
? ●Connection.BeginTrans方法:啟動(dòng)一個(gè)事務(wù); ? ?
? ●Connection.CommitTrans方法:完成/提交一個(gè)事務(wù); ? ?
? ●Connection.RollBackTrans方法:撤消/放棄一個(gè)事務(wù)。 ? ?
? //啟動(dòng)一個(gè)事務(wù)操作 ? ?
? <% ? Conn.BeginTrans ? %> ? ? ?
? <% ? sqlText=“Insert ? into ? USER(userName,userPasswd) ? values(‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“usrName”) ? & ? “’,‘”&request(“usrPasswd”)&“’) ? ” ? %> ? ?
? <% ? conn.execute(sqlText) ? %> ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? //如果插入數(shù)據(jù)操作失敗,則事務(wù)向前回滾 ? ?
? <% ? conn.RollBackTrans ? %> ? ? ?
? <% ? response.Redirct ? RegisterFail.html ? %> ? ?
? <% ? end ? if ? %> ? ?
? <% ? sqlText=“Insert ? into ? USERDOC(userName,Age,Sex,PhoneNumber,Address) ? ”%> ? ?
? <% ? sqlText=sqlText ? & ? “values(‘”& ? request ? ?
? (“usrName”) ? & ? “’, ? ” ? & ? request(“Age”) ? %> ? ?
? <% ? sqlText=sqlText ? & ? “,‘” ? & ? request ? ?
? (“PhoneNum”) ? & ? “’,‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“Address”) ? & ? “’) ? ” ? %> ? ?
? //執(zhí)行事務(wù)單元中的第二條插入語句 ? ?
? <% ? conn.execute(sqlText) ? %> ? ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? //如果操作失敗,則事務(wù)向前回滾 ? ?
? <% ? conn.RollBackTrans ? %> ? ? ?
? <% ? response.Redirct ? RegisterFail.html ? %> ? ?
? <% ? end ? if ? %> ? ?
? //如果整個(gè)事務(wù)操作執(zhí)行正確,則提交事務(wù) ? ?
? <% ? Conn.CommitTrans ? %> ? ? ?
? //轉(zhuǎn)向注冊(cè)成功處理頁(yè)面 ? ?
? <% ? response.Redirct ? RegisterOk.html ? %> ? ? ?
? 方法二 ? ?
? 可以利用數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)部的事務(wù)處理機(jī)制,通過在數(shù)據(jù)庫(kù)服務(wù)器中編寫包含事務(wù)的存儲(chǔ)過程,完成對(duì)數(shù)據(jù)操作的事務(wù)處理。同時(shí),利用ADO組件調(diào)用存儲(chǔ)過程,還可以根據(jù)存儲(chǔ)過程的返回代碼判斷事務(wù)處理是否執(zhí)行成功。 ? ?
? 在數(shù)據(jù)庫(kù)系統(tǒng)中,每一條SQL語句都是一個(gè)事務(wù)。因此可以保證每條語句要么完成,要么退回到開始之處。但是如果希望一組SQL語句的操作要么全部完成,要么全部無效,就需要利用數(shù)據(jù)庫(kù)的事務(wù)處理機(jī)制來實(shí)現(xiàn)。 ? ?
? 在數(shù)據(jù)庫(kù)中生成存儲(chǔ)過程的主要代碼如下: ? ?
? Create ? proc ? RegisterUser ? ?
? (@usrName ? varchar(30), ? @usrPasswd ? varchar(30),@age ? int, ? @PhoneNum ? varchar(20), ? @Address ? varchar(50) ? ) ? ?
? as ? ?
? begin ? ?
? //顯示定義并開始一個(gè)事務(wù) ? ?
? begin ? tran ? ? ?
? insert ? into ? USER(userName,userPasswd) ? values(@usrName,@usrPasswd) ? ?
? if ? @@error<>0 ? ?
? begin ? ?
? //操作失敗,則事務(wù)回滾 ? ?
? rollback ? tran ? ? ?
? //返回存儲(chǔ)過程,并設(shè)置返回碼為事務(wù)操作失敗 ? ?
? return ? -1 ? ? ?
? end ? ?
? insert ? into ? USERDOC(userName,age,sex,PhoneNumber,Address) ? ? ?
? values(@Usrname,@age,@PhoneNum,@Address) ? ?
? if ? @@error<>0 ? ?
? begin ? ?
? //操作失敗,則事務(wù)回滾 ? ?
? rollback ? tran ? ? ?
? return ? -1 ? ?
? end ? ?
? //如果操作執(zhí)行正確,則提交事務(wù) ? ?
? commit ? tran ? ? ?
? return ? 0 ? ?
? end ? ?
? 在ASP腳本中調(diào)用數(shù)據(jù)庫(kù)存儲(chǔ)過程的主要代碼如下: ? ?
? <% ? Set ? Comm=server.CreateObject ? ?
? (“ADODB.Command”) ? %> ? ?
? <% ? Set ? Comm.ActiveConnection=conn ? %> ? ?
? <% ? Comm.CommandType=adCmdStoredProc ? %> ? ?
? <% ? Comm.CommandText=“RegisterUser” ? %> ? ?
? //創(chuàng)建存儲(chǔ)過程返回參數(shù)對(duì)象 ? ?
? <% ? Set ? RetCode=Comm.CreateParameter ? ?
? (“RetCode”,adInteger,adParamReturnValue) ? %> ? ? ?
? //創(chuàng)建存儲(chǔ)過程輸入?yún)?shù)對(duì)象 ? ?
? <% ? Set ? usrName=Comm.CreateParameter ? ?
? (“usrName”,adVarchar,adParamInput,30) ? %> ? ? ?
? <% ? Set ? usrPwd=Comm.CreateParameter ? ?
? (“usrPasswd”,adVarchar,adParamInput,30) ? %> ? ?
? <% ? Set ? age=Comm.CreateParameter(“age”,adInteger,adParamInput) ? %> ? ?
? <% ? Set ? PhoneNum=Comm.CreateParameter ? ?
? (“PhoneNum”,adVarchar,adParamInput, ? 20) ? %> ? ?
? <% ? Set ? Address=Comm.CreateParameter(“Address”,adVarchar,adParamInput,50) ? %> ? ?
? <% ? Comm.Parameters.Append ? usrName ? %> ? ?
? <% ? Comm.Parameters.Append ? usrPwd ? %> ? ?
? <% ? Comm.Parameters.Append ? age ? %> ? ?
? <% ? Comm.Parameters.Append ? PhoneNum ? %> ? ?
? <% ? Comm.Parameters.Append ? Address ? %> ? ?
? <% ? Comm.Parameters(“usrName”)=request ? ?
? (“usrName”) ? %> ? ?
? <% ? Comm.Parameters(“usrPasswd”)=request ? ?
? (“usrPasswd”) ? %> ? ?
? <% ? Comm.Parameters(“age”)=request(“age”) ? %> ? ?
? <% ? Comm.Parameters(“PhoneNum”)=request ? ?
? (“PhoneNum”) ? %> ? ?
? <% ? Comm.Parameters(“Address”)=request ? ?
? (“Address”) ? %> ? ?
? <% ? Comm.Execute ? %> ? ?
? <% ? RetValue=Cint(Comm(“RetCode”)) ? %> ? ?
? //根據(jù)數(shù)據(jù)庫(kù)存儲(chǔ)過程返回代碼判斷注冊(cè)是否成功 ? ?
? <% ? if ? RetValue< ? 0 ? then ? %> ? ? ?
? <% ? response.Redirect ? RegisterFail.html ? %> ? ?
? <% ? else ? %> ? ?
? <% ? response.Redirect ? RegisterOk.html ? %> ? ?
? <% ? end ? if ? %> ? ?
? 方法三 ? ?
? 利用MTS(Microsoft ? Transaction ? Server)組件的事務(wù)處理機(jī)制實(shí)現(xiàn)事務(wù)處理時(shí),需要特別注意的是,這種機(jī)制下的事務(wù)不能跨越多個(gè)ASP頁(yè),如果一個(gè)事務(wù)處理需要來自多個(gè)組件的對(duì)象,則須將對(duì)這些對(duì)象的操作組合在一個(gè)ASP頁(yè)中。 ? ?
? 首先需要在頁(yè)首添加指令@TRANSACTION,將一個(gè)ASP頁(yè)面聲明為事務(wù)性。@TRANSACTION指令必須在一頁(yè)中的第一行,否則將產(chǎn)生錯(cuò)誤。當(dāng)頁(yè)面中ASP腳本處理結(jié)束時(shí),當(dāng)前事務(wù)即告結(jié)束。 ? ?
? <%@ ? TRANSACTION=Required ? Language= ? ?
? VB ? Script ? %> ? ?
? //事務(wù)執(zhí)行成功觸發(fā)事件 ? ?
? <% ? Sub ? OnTransactionCommit() ? %> ? ? ?
? <% ? response.Redirect ? RegisterOk.html ? %> ? ?
? <% ? End ? Sub ? %> ? ?
? //事物執(zhí)行失敗觸發(fā)事件 ? ?
? <% ? Sub ? OnTransactionAbort() ? %> ? ? ?
? <% ? response.Redirect ? RegisterFail.html ? %> ? ?
? <% ? End ? Sub ? %> ? ?
? <% ? sqlText=“Insert ? into ? USER(userName,userPasswd) ? values(‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“usrName”) ? & ? “’,‘” ? &request(“usrPasswd”)&“’) ? ” ? %> ? ?
? <% ? conn.execute(sqlText) ? %> ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? <% ? ObjectContext.SetAbort ? %> ? ?
? <% ? end ? if ? %> ? ?
? <% ? sqlText=“Insert ? into ? USERDOC(userName,Age,Sex,PhoneNumber,Address) ? ”%> ? ?
? <% ? sqlText=sqlText ? & ? “values(‘” ? & ? request ? ?
? (“usrName”)& ? “’, ? ” ? & ? request(“Age”) ? %> ? ?
? <% ? sqlText=sqlText ? & ? “,’” ? & ? request ? ?
? (“PhoneNum”) ? & ? “’,‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“Address”) ? & ? “’) ? ” ? %> ? ?
? <% ? conn.execute(sqlText) ? %> ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? <% ? ObjectContext.SetAbort ? %> ? ?
? <% ? end ? if ? %> ? ?
? <% ? ObjectContext.SetComplete ? %> ? ?
? 方案比較 ? ?
? 從靈活的角度考慮,選擇采用ASP數(shù)據(jù)庫(kù)組件的方法具有一定的優(yōu)勢(shì):既可以選用ADO數(shù)據(jù)庫(kù)組件完成事務(wù)處理,同時(shí)還可以根據(jù)實(shí)際需要,定制自己的數(shù)據(jù)庫(kù)組件(只要滿足ASP組件編寫規(guī)范即可)。如果從數(shù)據(jù)庫(kù)事務(wù)處理的可靠性等角度考慮,則采用數(shù)據(jù)庫(kù)內(nèi)部的事務(wù)處理存儲(chǔ)過程更好。這樣可以直接利用數(shù)據(jù)庫(kù)事務(wù)機(jī)制完成應(yīng)用程序的邏輯事務(wù)處理,安全可靠,并且減少了Web服務(wù)器與數(shù)據(jù)庫(kù)服務(wù)器之間的數(shù)據(jù)交互。這一點(diǎn)對(duì)分布式數(shù)據(jù)庫(kù)系統(tǒng)尤為重要。采用MTS組件的事務(wù)處理方法的優(yōu)勢(shì)在于:由MTS服務(wù)器直接控制和管理組件(在MTS中注冊(cè)的組件)操作的完成和撤消,具有良好的擴(kuò)展空間和應(yīng)用前景,可以充分發(fā)揮MTS的技術(shù)優(yōu)勢(shì),增強(qiáng)網(wǎng)絡(luò)應(yīng)用的容錯(cuò)性能,提高IIS ? Web服務(wù)器的動(dòng)態(tài)性能。
? 1.ASP事務(wù)處理基本原理 ? ?
? ASP ? 事務(wù)處理是以Microsoft ? Transaction ? Server(簡(jiǎn)稱MTS)為基礎(chǔ)的。MTS ? 是一個(gè)運(yùn)行于Windows ? NT環(huán)境下的事務(wù)處理系統(tǒng),用于開發(fā)、配置和管理高性能、可分級(jí)的、有魯棒性的企業(yè) ? Internet ? 和 ? Intranet ? 服務(wù)器應(yīng)用程序。MTS為開發(fā)分布式的,基于組件的應(yīng)用程序提供了一個(gè)應(yīng)用程序設(shè)計(jì)模型,它也為配置和管理這些應(yīng)用程序提供了一個(gè)運(yùn)行環(huán)境。 ? ?
? 創(chuàng)建事務(wù)性腳本的功能內(nèi)置在 ? Internet ? Information ? Server中。如果您安裝了 ? Microsoft ? Transaction ? Server,就可以將組件打包,以使組件在事務(wù)內(nèi)部運(yùn)行。 ? ?
? 事務(wù)是整體成功或失敗的操作,事務(wù)處理常用于對(duì)數(shù)據(jù)庫(kù)進(jìn)行可靠地更新。在對(duì)數(shù)據(jù)庫(kù)進(jìn)行許多相關(guān)更改或同時(shí)更新多個(gè)數(shù)據(jù)庫(kù)時(shí),要保證所有更改都被正確執(zhí)行。如果這些更改中的任何一個(gè)失敗,都需要恢復(fù)數(shù)據(jù)庫(kù)表的原始狀態(tài)。 ? ?
? 如果沒有 ? MTS,您就需要編寫腳本和組件,手工跟蹤請(qǐng)求的更改情況,以便在某些更改失敗時(shí)恢復(fù)數(shù)據(jù)。使用 ? MTS,您只需簡(jiǎn)單的將您的腳本和組件聲明為“需要事務(wù)”并讓 ? MTS ? 處理事務(wù)的一致性。事務(wù)處理只適用于數(shù)據(jù)庫(kù)訪問;MTS ? 不能對(duì)文件系統(tǒng)或其他的非事務(wù)性資源的更改進(jìn)行恢復(fù)操作。應(yīng)用程序所訪問的數(shù)據(jù)庫(kù)必須為 ? MTS ? 所支持。目前,MTS ? 支持 ? Microsoft ? SQL ? Server ? 及任何支持 ? XA ? 協(xié)議(由 ? X/Open ? 協(xié)會(huì)制定)的服務(wù)器。MTS ? 將繼續(xù)擴(kuò)展對(duì)其他數(shù)據(jù)庫(kù)的支持。 ? ?
? 事務(wù)不能跨越多個(gè) ? ASP ? 頁(yè)。如果一個(gè)事務(wù)需要來自多個(gè)組件的對(duì)象,則須將使用這些對(duì)象的操作組合在一個(gè) ? ASP ? 頁(yè)中。例如,假定有一個(gè)組件用于更新工資單數(shù)據(jù)庫(kù),還有一個(gè)組件用于更新人力資源數(shù)據(jù)庫(kù)中的員工記錄。為了記錄一個(gè)員工的新的工資信息,您需要編寫這樣一個(gè)腳本,該腳本在一個(gè)事務(wù)環(huán)境中調(diào)用這兩個(gè)組件,一個(gè)用于更新工資單數(shù)據(jù)庫(kù),另一個(gè)用于更新人力資源數(shù)據(jù)庫(kù)中的員工等級(jí)。 ? ?
? ?
? 2.在ASP腳本中編寫事務(wù)型應(yīng)用 ? ?
? 1. ? 聲明事務(wù)性腳本 ? ?
? 在將一個(gè)ASP頁(yè)聲明為事務(wù)性時(shí),此頁(yè)中的任何腳本命令和對(duì)象都運(yùn)行在同一個(gè)事務(wù)環(huán)境中,MTS處理生成事務(wù)的細(xì)節(jié)并決定事務(wù)成功(提交)或失敗(終止)。要將某個(gè)頁(yè)聲明為事務(wù)性,可在頁(yè)首添加 ? @TRANSACTION ? 指令: ? ?
? ?
? value ? 參數(shù)可以是下列之一: ? ?
? Requires_New ? :啟動(dòng)一個(gè)新的事務(wù)。 ? ?
? Required ? : ? 啟動(dòng)一個(gè)新的事務(wù)。 ? ?
? Supported: ? 不啟動(dòng)事務(wù)。 ? ?
? Not_Supported: ? 不啟動(dòng)事務(wù)。 ? ?
? @TRANSACTION ? 指令必須在一頁(yè)中的第一行,否則將產(chǎn)生錯(cuò)誤。必須將該指令添加到需要在事務(wù)下運(yùn)行的每一頁(yè)中。當(dāng)腳本處理結(jié)束時(shí),當(dāng)前事務(wù)即告結(jié)束。 ? ?
? 如果事務(wù)被終止,MTS將恢復(fù)對(duì)支持事務(wù)的資源的任何更改。目前,僅數(shù)據(jù)庫(kù)服務(wù)器完全支持事務(wù),因?yàn)閿?shù)據(jù)庫(kù)中的數(shù)據(jù)對(duì)于企業(yè)應(yīng)用是最為關(guān)鍵的。MTS不對(duì)硬盤上的文件、會(huì)話和應(yīng)用程序的變量、集合等的改變進(jìn)行恢復(fù),然而您可以如下文所述,通過編寫事務(wù)事件來編寫恢復(fù)變量和集合的腳本。在某些時(shí)候,您的腳本也可以顯式的提交或終止一個(gè)事務(wù),如向文件寫數(shù)據(jù)失敗時(shí)。 ? ?
? 2. ? 提交或終止腳本 ? ?
? 利用 ? ObjectContext ? 對(duì)象可以提交或放棄一項(xiàng)由MTS管理的事務(wù),為此,ObjectContext ? 對(duì)象提供了兩個(gè)方法: ? ?
? (1)SetComplete ? 方法 ? ?
? 聲明腳本不了解事務(wù)未完成的原因。如果事務(wù)中的所有組件都調(diào)用 ? SetComplete,事務(wù)將完成。 ? ?
? (2)SetAbort ? 方法 ? ?
? 聲明被腳本初始化的事務(wù)未完成,無法更新源。 ? ?
? 示例: ? ?
? <%@ ? Transaction ? = ? Required ? %> ?
? <% ?
? Set ? CurrentQOB ? = ? Server.CreateObject("Mylib. ? Inventory") ? ' ? 創(chuàng)建Inventory對(duì)象 ?
? Set ? CurrentBorrow ? = ? Server.CreateObject ? ("Mylib.Borrow") ? ' ? 創(chuàng)建Borrow對(duì)象 ?
? CheckQuantity ? = ? Request.Form("QuantityTo ? Borrow") ?
? CheckBook ? = ? Request.Form("BookCode") ?
? QuantityStatus ? = ? CurrentQOB.CheckQOB ? (CheckQuantity,CheckBook)'檢查存書量 ?
? If ? QuantityStatus ? = ? None ? '如果存書量不足 ?
? ObjectContext.SetAbort ? '終止事務(wù) ?
? Response.Write ? "對(duì)不起,存書量不足!" ?
? Else'如果存書量充足 ?
? ObjectContext.SetComplete ? '繼續(xù)執(zhí)行事務(wù) ?
? Account ? = ? Request.Form("AccountIn") ?
? Saleupdate ? = ? CurrentBorrow.PostIt(Account) ?
? End ? If ?
? %> ?
? ?
? ?
? 這里示范使用 ? SetAbort ? 和SetComplete ? 的方法。假設(shè)有一個(gè)網(wǎng)上有償借閱圖書館的主頁(yè),其中,BorrowBookData.htm ? 文件獲取處理借閱圖書請(qǐng)求所需的數(shù)據(jù)。第二個(gè)文件BorrowVerify.asp ? 中的腳本使用兩個(gè)對(duì)象Inventory ? 和 ? Borrow ? 來處理借閱(注意,在本文所舉的例子中,使用了一些作者自己開發(fā)的Web服務(wù)器端ActiveX組件對(duì)象,如對(duì)象Inventory ? 和 ? Borrow等,在實(shí)際應(yīng)用中,這些組件對(duì)象需由讀者自行開發(fā))。如果 ? Inventory ? 返回了錯(cuò)誤代碼表示存書不足,就會(huì)調(diào)用 ? SetAbort。如果 ? Inventory ? 對(duì)象沒有返回錯(cuò)誤代碼,將會(huì)調(diào)用 ? SetComplete ? 處理借閱請(qǐng)求。 ? ?
? BorrowBookData.htm ? 源文件: ? ?
? ?
? ?
? <%@ ? TRANSACTION ? = ? Required ? %> ?
? <%Response.Buffer ? = ? True ? '緩存輸出 ? %> ?
? <HTML> ?
? <BODY> ?
? <H1>網(wǎng)上有償借閱圖書館</H1> ?
? <% ? ' ? 創(chuàng)建作者自己開發(fā)的ActiveX組件對(duì)象 ?
? Set ? LibAction ? = ? Server.CreateObject ? ("MyExample.LibComponent") ?
? ' ? 根據(jù)借閱者輸入的帳戶、密碼進(jìn)行業(yè)務(wù)處理 ?
? LibAction.Borrow(Request.Form("Account ? Num"),Request.Form("Password")) ?
? %> ?
? </BODY> ?
? </HTML> ?
? <% ? ' ? 如果借閱者帳戶有效顯示下頁(yè) ?
? Sub ? OnTransactionCommit() ?
? Response.Write ? "<HTML>" ?
? Response.Write ? "<BODY>" ?
? Response.Write ? "帳戶有效!" ?
? Response.Write ? "</BODY>" ?
? Response.Write ? "</HTML>" ?
? Response.Flush() ?
? End ? sub ? %> ?
? <% ? ' ? 如果借閱者帳戶無效顯示下頁(yè) ?
? Sub ? OnTransactionAbort() ?
? Response.Clear() ?
? Response.Write ? "<HTML>" ?
? Response.Write ? "<BODY>" ?
? Response.Write ? "帳戶無效!" ?
? Response.Write ? "</BODY>" ?
? Response.Write ? "</HTML>" ?
? Response.Flush() ?
? End ? sub ? %> ?
? ?
? ?
? 3. ? 編寫事務(wù)事件 ? ?
? 腳本本身不能決定事務(wù)是成功還是失敗。但是,可以編寫提交或終止事務(wù)時(shí)被調(diào)用的事件。為此,ObjectContext ? 對(duì)象提供了兩個(gè)事件: ? ?
? (1)OnTransactionCommit ? 事件 ? ?
? 它在一個(gè)已處理的腳本事務(wù)提交后發(fā)生。該事件發(fā)生時(shí),如果腳本中有 ? OnTransactionCommit ? 子例程,IIS ? 將處理該子例程。 ? ?
? (2)OnTransactionAbort ? 事件 ? ?
? 如果事務(wù)異常終止,就會(huì)發(fā)生該事件。當(dāng) ? OnTransactionAbort ? 事件發(fā)生時(shí),如果腳本中有 ? OnTransactionAbort ? 子程序,則 ? IIS ? 將執(zhí)行它。 ? ?
? 例如,假設(shè)有一個(gè)根據(jù)借閱者帳戶、密碼進(jìn)行業(yè)務(wù)處理的腳本,并且您需要針對(duì)事務(wù)的不同狀態(tài)將不同的頁(yè)返回給用戶,那么就可以使用 ? OnTransactionCommit ? 和 ? OnTransactionAbort ? 事件來編寫對(duì)用戶的不同響應(yīng)。?
_______________________
-------------------------------------------------------------------------------- ?
? ? 運(yùn)氣 ? 于 ? 8/24/2001 ? 9:46:19 ? AM ? 加貼在 ? Joy ? ASP ? ←返回版面: ? ? ? ?
? 在開發(fā)Web應(yīng)用時(shí),無一例外地需要訪問數(shù)據(jù)庫(kù),以完成對(duì)數(shù)據(jù)的查詢、插入、更新、刪除等操作。受應(yīng)用邏輯的影響,有時(shí)需要將多條數(shù)據(jù)庫(kù)操作指令組成一個(gè)工作單元(事務(wù))。在數(shù)據(jù)庫(kù)中,所謂事務(wù)是指一組邏輯操作單元,它使數(shù)據(jù)從一種狀態(tài)變換到另一種狀態(tài)。為確保數(shù)據(jù)庫(kù)中數(shù)據(jù)的一致性,應(yīng)當(dāng)用離散的成組的邏輯單元操作數(shù)據(jù):當(dāng)它全部完成時(shí),數(shù)據(jù)的一致性可以保持;而當(dāng)單元中的一部分操作失敗時(shí),整個(gè)事務(wù)會(huì)被全部忽略,所有從起始點(diǎn)以后的操作全部退回到開始狀態(tài)。 ? ?
? 實(shí)際上,在默認(rèn)方式下對(duì)數(shù)據(jù)庫(kù)的每一次操作都是隱含的事務(wù)處理。本文以一個(gè)典型的用戶注冊(cè)程序?yàn)槔?#xff0c;介紹三種利用ASP實(shí)現(xiàn)事務(wù)處理的方法:基于ASP數(shù)據(jù)庫(kù)組件的解決方法、基于數(shù)據(jù)庫(kù)內(nèi)部的事務(wù)處理機(jī)制的解決方法和基于MTS組件的解決方法。 ? ?
? ?
? 程序功能 ? ?
? 在SQL ? Server數(shù)據(jù)庫(kù)中建立兩個(gè)表:USER表和USERDOC表。其中USER表中存放的是注冊(cè)用戶的用戶名和密碼,USERDOC表中存放的是該注冊(cè)用戶的個(gè)人資料,并且以用戶名為索引。下面是表USER和USERDOC的定義: ? ?
? Create ? Table ? USER(userName ? varchar(30),userPasswd ? varchar(30)) ? ?
? Create ? Table ? USERDOC(userName ? varchar(30),Age ? int,Sex ? int,PhoneNumber ? varchar(20),Address ? varchar(50)) ? ?
? 當(dāng)用戶請(qǐng)求注冊(cè)時(shí),ASP腳本先將用戶名和密碼插入到USER表中,然后在USERDOC表中插入用戶個(gè)人信息(年齡、性別、聯(lián)系電話和家庭住址等)。同時(shí),應(yīng)用程序還必須保證USER表中的每一條記錄在USERDOC表中都有相應(yīng)的記錄。 ? ?
? 方法一 ? ?
? 利用ASP內(nèi)置ADO組件中的Connection對(duì)象可以實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)操作的事務(wù)性處理。Connection對(duì)象的部分方法如下: ? ?
? ●Connection.BeginTrans方法:啟動(dòng)一個(gè)事務(wù); ? ?
? ●Connection.CommitTrans方法:完成/提交一個(gè)事務(wù); ? ?
? ●Connection.RollBackTrans方法:撤消/放棄一個(gè)事務(wù)。 ? ?
? //啟動(dòng)一個(gè)事務(wù)操作 ? ?
? <% ? Conn.BeginTrans ? %> ? ? ?
? <% ? sqlText=“Insert ? into ? USER(userName,userPasswd) ? values(‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“usrName”) ? & ? “’,‘”&request(“usrPasswd”)&“’) ? ” ? %> ? ?
? <% ? conn.execute(sqlText) ? %> ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? //如果插入數(shù)據(jù)操作失敗,則事務(wù)向前回滾 ? ?
? <% ? conn.RollBackTrans ? %> ? ? ?
? <% ? response.Redirct ? RegisterFail.html ? %> ? ?
? <% ? end ? if ? %> ? ?
? <% ? sqlText=“Insert ? into ? USERDOC(userName,Age,Sex,PhoneNumber,Address) ? ”%> ? ?
? <% ? sqlText=sqlText ? & ? “values(‘”& ? request ? ?
? (“usrName”) ? & ? “’, ? ” ? & ? request(“Age”) ? %> ? ?
? <% ? sqlText=sqlText ? & ? “,‘” ? & ? request ? ?
? (“PhoneNum”) ? & ? “’,‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“Address”) ? & ? “’) ? ” ? %> ? ?
? //執(zhí)行事務(wù)單元中的第二條插入語句 ? ?
? <% ? conn.execute(sqlText) ? %> ? ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? //如果操作失敗,則事務(wù)向前回滾 ? ?
? <% ? conn.RollBackTrans ? %> ? ? ?
? <% ? response.Redirct ? RegisterFail.html ? %> ? ?
? <% ? end ? if ? %> ? ?
? //如果整個(gè)事務(wù)操作執(zhí)行正確,則提交事務(wù) ? ?
? <% ? Conn.CommitTrans ? %> ? ? ?
? //轉(zhuǎn)向注冊(cè)成功處理頁(yè)面 ? ?
? <% ? response.Redirct ? RegisterOk.html ? %> ? ? ?
? 方法二 ? ?
? 可以利用數(shù)據(jù)庫(kù)系統(tǒng)內(nèi)部的事務(wù)處理機(jī)制,通過在數(shù)據(jù)庫(kù)服務(wù)器中編寫包含事務(wù)的存儲(chǔ)過程,完成對(duì)數(shù)據(jù)操作的事務(wù)處理。同時(shí),利用ADO組件調(diào)用存儲(chǔ)過程,還可以根據(jù)存儲(chǔ)過程的返回代碼判斷事務(wù)處理是否執(zhí)行成功。 ? ?
? 在數(shù)據(jù)庫(kù)系統(tǒng)中,每一條SQL語句都是一個(gè)事務(wù)。因此可以保證每條語句要么完成,要么退回到開始之處。但是如果希望一組SQL語句的操作要么全部完成,要么全部無效,就需要利用數(shù)據(jù)庫(kù)的事務(wù)處理機(jī)制來實(shí)現(xiàn)。 ? ?
? 在數(shù)據(jù)庫(kù)中生成存儲(chǔ)過程的主要代碼如下: ? ?
? Create ? proc ? RegisterUser ? ?
? (@usrName ? varchar(30), ? @usrPasswd ? varchar(30),@age ? int, ? @PhoneNum ? varchar(20), ? @Address ? varchar(50) ? ) ? ?
? as ? ?
? begin ? ?
? //顯示定義并開始一個(gè)事務(wù) ? ?
? begin ? tran ? ? ?
? insert ? into ? USER(userName,userPasswd) ? values(@usrName,@usrPasswd) ? ?
? if ? @@error<>0 ? ?
? begin ? ?
? //操作失敗,則事務(wù)回滾 ? ?
? rollback ? tran ? ? ?
? //返回存儲(chǔ)過程,并設(shè)置返回碼為事務(wù)操作失敗 ? ?
? return ? -1 ? ? ?
? end ? ?
? insert ? into ? USERDOC(userName,age,sex,PhoneNumber,Address) ? ? ?
? values(@Usrname,@age,@PhoneNum,@Address) ? ?
? if ? @@error<>0 ? ?
? begin ? ?
? //操作失敗,則事務(wù)回滾 ? ?
? rollback ? tran ? ? ?
? return ? -1 ? ?
? end ? ?
? //如果操作執(zhí)行正確,則提交事務(wù) ? ?
? commit ? tran ? ? ?
? return ? 0 ? ?
? end ? ?
? 在ASP腳本中調(diào)用數(shù)據(jù)庫(kù)存儲(chǔ)過程的主要代碼如下: ? ?
? <% ? Set ? Comm=server.CreateObject ? ?
? (“ADODB.Command”) ? %> ? ?
? <% ? Set ? Comm.ActiveConnection=conn ? %> ? ?
? <% ? Comm.CommandType=adCmdStoredProc ? %> ? ?
? <% ? Comm.CommandText=“RegisterUser” ? %> ? ?
? //創(chuàng)建存儲(chǔ)過程返回參數(shù)對(duì)象 ? ?
? <% ? Set ? RetCode=Comm.CreateParameter ? ?
? (“RetCode”,adInteger,adParamReturnValue) ? %> ? ? ?
? //創(chuàng)建存儲(chǔ)過程輸入?yún)?shù)對(duì)象 ? ?
? <% ? Set ? usrName=Comm.CreateParameter ? ?
? (“usrName”,adVarchar,adParamInput,30) ? %> ? ? ?
? <% ? Set ? usrPwd=Comm.CreateParameter ? ?
? (“usrPasswd”,adVarchar,adParamInput,30) ? %> ? ?
? <% ? Set ? age=Comm.CreateParameter(“age”,adInteger,adParamInput) ? %> ? ?
? <% ? Set ? PhoneNum=Comm.CreateParameter ? ?
? (“PhoneNum”,adVarchar,adParamInput, ? 20) ? %> ? ?
? <% ? Set ? Address=Comm.CreateParameter(“Address”,adVarchar,adParamInput,50) ? %> ? ?
? <% ? Comm.Parameters.Append ? usrName ? %> ? ?
? <% ? Comm.Parameters.Append ? usrPwd ? %> ? ?
? <% ? Comm.Parameters.Append ? age ? %> ? ?
? <% ? Comm.Parameters.Append ? PhoneNum ? %> ? ?
? <% ? Comm.Parameters.Append ? Address ? %> ? ?
? <% ? Comm.Parameters(“usrName”)=request ? ?
? (“usrName”) ? %> ? ?
? <% ? Comm.Parameters(“usrPasswd”)=request ? ?
? (“usrPasswd”) ? %> ? ?
? <% ? Comm.Parameters(“age”)=request(“age”) ? %> ? ?
? <% ? Comm.Parameters(“PhoneNum”)=request ? ?
? (“PhoneNum”) ? %> ? ?
? <% ? Comm.Parameters(“Address”)=request ? ?
? (“Address”) ? %> ? ?
? <% ? Comm.Execute ? %> ? ?
? <% ? RetValue=Cint(Comm(“RetCode”)) ? %> ? ?
? //根據(jù)數(shù)據(jù)庫(kù)存儲(chǔ)過程返回代碼判斷注冊(cè)是否成功 ? ?
? <% ? if ? RetValue< ? 0 ? then ? %> ? ? ?
? <% ? response.Redirect ? RegisterFail.html ? %> ? ?
? <% ? else ? %> ? ?
? <% ? response.Redirect ? RegisterOk.html ? %> ? ?
? <% ? end ? if ? %> ? ?
? 方法三 ? ?
? 利用MTS(Microsoft ? Transaction ? Server)組件的事務(wù)處理機(jī)制實(shí)現(xiàn)事務(wù)處理時(shí),需要特別注意的是,這種機(jī)制下的事務(wù)不能跨越多個(gè)ASP頁(yè),如果一個(gè)事務(wù)處理需要來自多個(gè)組件的對(duì)象,則須將對(duì)這些對(duì)象的操作組合在一個(gè)ASP頁(yè)中。 ? ?
? 首先需要在頁(yè)首添加指令@TRANSACTION,將一個(gè)ASP頁(yè)面聲明為事務(wù)性。@TRANSACTION指令必須在一頁(yè)中的第一行,否則將產(chǎn)生錯(cuò)誤。當(dāng)頁(yè)面中ASP腳本處理結(jié)束時(shí),當(dāng)前事務(wù)即告結(jié)束。 ? ?
? <%@ ? TRANSACTION=Required ? Language= ? ?
? VB ? Script ? %> ? ?
? //事務(wù)執(zhí)行成功觸發(fā)事件 ? ?
? <% ? Sub ? OnTransactionCommit() ? %> ? ? ?
? <% ? response.Redirect ? RegisterOk.html ? %> ? ?
? <% ? End ? Sub ? %> ? ?
? //事物執(zhí)行失敗觸發(fā)事件 ? ?
? <% ? Sub ? OnTransactionAbort() ? %> ? ? ?
? <% ? response.Redirect ? RegisterFail.html ? %> ? ?
? <% ? End ? Sub ? %> ? ?
? <% ? sqlText=“Insert ? into ? USER(userName,userPasswd) ? values(‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“usrName”) ? & ? “’,‘” ? &request(“usrPasswd”)&“’) ? ” ? %> ? ?
? <% ? conn.execute(sqlText) ? %> ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? <% ? ObjectContext.SetAbort ? %> ? ?
? <% ? end ? if ? %> ? ?
? <% ? sqlText=“Insert ? into ? USERDOC(userName,Age,Sex,PhoneNumber,Address) ? ”%> ? ?
? <% ? sqlText=sqlText ? & ? “values(‘” ? & ? request ? ?
? (“usrName”)& ? “’, ? ” ? & ? request(“Age”) ? %> ? ?
? <% ? sqlText=sqlText ? & ? “,’” ? & ? request ? ?
? (“PhoneNum”) ? & ? “’,‘” ? %> ? ?
? <% ? sqlText=sqlText ? & ? request(“Address”) ? & ? “’) ? ” ? %> ? ?
? <% ? conn.execute(sqlText) ? %> ? ?
? <% ? if ? conn.Errors.Count>0 ? then ? %> ? ?
? <% ? conn.Errors.Clear ? %> ? ?
? <% ? ObjectContext.SetAbort ? %> ? ?
? <% ? end ? if ? %> ? ?
? <% ? ObjectContext.SetComplete ? %> ? ?
? 方案比較 ? ?
? 從靈活的角度考慮,選擇采用ASP數(shù)據(jù)庫(kù)組件的方法具有一定的優(yōu)勢(shì):既可以選用ADO數(shù)據(jù)庫(kù)組件完成事務(wù)處理,同時(shí)還可以根據(jù)實(shí)際需要,定制自己的數(shù)據(jù)庫(kù)組件(只要滿足ASP組件編寫規(guī)范即可)。如果從數(shù)據(jù)庫(kù)事務(wù)處理的可靠性等角度考慮,則采用數(shù)據(jù)庫(kù)內(nèi)部的事務(wù)處理存儲(chǔ)過程更好。這樣可以直接利用數(shù)據(jù)庫(kù)事務(wù)機(jī)制完成應(yīng)用程序的邏輯事務(wù)處理,安全可靠,并且減少了Web服務(wù)器與數(shù)據(jù)庫(kù)服務(wù)器之間的數(shù)據(jù)交互。這一點(diǎn)對(duì)分布式數(shù)據(jù)庫(kù)系統(tǒng)尤為重要。采用MTS組件的事務(wù)處理方法的優(yōu)勢(shì)在于:由MTS服務(wù)器直接控制和管理組件(在MTS中注冊(cè)的組件)操作的完成和撤消,具有良好的擴(kuò)展空間和應(yīng)用前景,可以充分發(fā)揮MTS的技術(shù)優(yōu)勢(shì),增強(qiáng)網(wǎng)絡(luò)應(yīng)用的容錯(cuò)性能,提高IIS ? Web服務(wù)器的動(dòng)態(tài)性能。
轉(zhuǎn)載于:https://blog.51cto.com/jetking/28300
總結(jié)
以上是生活随笔為你收集整理的ASP中事务处理资料收集的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tomcat 下载
- 下一篇: Fences有一个桌面分区消失了怎么办