Asp事務(wù)處理
更新時(shí)間:2006年09月14日 00:00:00 作者:
在編程中,經(jīng)常需要使用事務(wù)。所謂事務(wù),就是一系列必須都成功的操作,只要有一步操作失敗,所有其他的步驟也必須撤銷(xiāo)。比如用ASP開(kāi)發(fā)一個(gè)網(wǎng)絡(luò)硬盤(pán)系統(tǒng),其用戶(hù)注冊(cè)部分要做的事有:
1、將用戶(hù)信息記入數(shù)據(jù)庫(kù)
2、為用戶(hù)開(kāi)個(gè)文件夾用于存儲(chǔ)
3、初始化用戶(hù)操作日志
這三步必須使用事務(wù),否則萬(wàn)一磁盤(pán)操作失敗,而沒(méi)有撤銷(xiāo)數(shù)據(jù)庫(kù)操作,就會(huì)造成只能登陸而不能操作的“死用戶(hù)”現(xiàn)象。
由于數(shù)據(jù)庫(kù)系統(tǒng)特殊的發(fā)展歷史,小至Access,大到DB2,無(wú)不帶有事務(wù)支持。因此上述步驟可以如下表示:
以下是引用片段:
On Error Resume Next
第一步:
在事務(wù)環(huán)境下把用戶(hù)信息記入數(shù)據(jù)庫(kù)
If Err Then
關(guān)閉連接
退出
Else
第二步:創(chuàng)建文件夾
If Err Then
回滾第一步數(shù)據(jù)庫(kù)操作,退出
Else
第三步:在事務(wù)環(huán)境下操作日志數(shù)據(jù)庫(kù)
If Err Then
回滾第一步操作,刪除第二步建立的文件夾
退出
End If
End If
End If
提交第一步數(shù)據(jù)庫(kù)操作的事務(wù)
提交第二步數(shù)據(jù)庫(kù)操作的事務(wù)
End
每一步都需要進(jìn)行判斷,如果失敗,還需要手工回滾前面多步操作,使程序變得復(fù)雜、難懂。如果今后更新了程序,增加其他步驟,還需要嵌套更多層的If...Else...End If,使程序流程更加復(fù)雜。
正確的解決辦法是使用ASP的事務(wù)控制功能。IIS通過(guò)和MTS服務(wù)聯(lián)系,可以控制多種支持事務(wù)的系統(tǒng),當(dāng)程序發(fā)出“失敗”的信號(hào)時(shí),所有支持事務(wù)的系統(tǒng)均將自動(dòng)回滾,即使操作已經(jīng)正式完成;對(duì)不支持事務(wù)的操作也提供了方便的手工回滾方式。上面的例子用ASP事務(wù)控制功能重寫(xiě)如下:
<%@ TRANSACTION = Required %>
On Error Resume Next
Set Conn=Server.CreateObject("ADODB.Connection")
Conn.Open ....
Conn.Execute "INSERT...."
Conn.Close
Set Conn=Nothing
Set Conn2=Server.CreateObject("ADODB.Connection")
Conn2.Open ....
Conn2.Execute "INSERT...."
Conn2.Close
Set Conn2=Nothing
Set FSO=Server.CreateObject("Scripting.FilesystemObject")
FSO.CreateFolder "...."
If Err Then
ObjectContext.SetAbort '通知所有支持事務(wù)的組件回滾,并運(yùn)行手工回滾代碼
Else
ObjectContext.SetComplete
End If
Set FSO=Nothing
Sub OnTransactionAbort
Response.Write "錯(cuò)誤"
FSO.DeleteFile Server.Mappath("a.txt") 'FSO的手工回滾——?jiǎng)h除文件夾
End Sub
Sub OnTransactionCommit
Response.Write "勝利完成任務(wù)"
End Sub
%>
第一行的<%@ TRANSACTION = Required %>表示這一頁(yè)ASP文件需要MTS的事務(wù)支持。中間的各個(gè)操作都按普通順序書(shū)寫(xiě),而不用考慮回滾問(wèn)題。在程序最后判斷是否有錯(cuò)誤。如果有,調(diào)用ObjectContext的SetAbort方法,IIS會(huì)通過(guò)MTS服務(wù)通知所有支持事務(wù)的組件回滾(主要是數(shù)據(jù)庫(kù)),并且運(yùn)行Sub OnTransactionAbort對(duì)不支持事務(wù)的操作手工回滾;如果沒(méi)有發(fā)生錯(cuò)誤,調(diào)用ObjectContext的SetComplete方法,則會(huì)運(yùn)行Sub OnTransactionCommit來(lái)顯示成功的消息。
整個(gè)ASP程序不需要為判斷錯(cuò)誤和回滾操作書(shū)寫(xiě)多余的代碼,只須在最后進(jìn)行判斷,即使今后增加了多步操作,也只需要在Sub OnTransactionAbort中進(jìn)行控制即可,非常方便,程序員可以專(zhuān)注于過(guò)程編寫(xiě)而不是書(shū)寫(xiě)糾錯(cuò)代碼。
其實(shí)ASP還提供了許多更有用的功能,等著我們使用,千萬(wàn)不要以為ASP使用腳本語(yǔ)言,功能就一定弱。
以下是引用片段:
<%
'asp事務(wù)處理。
'測(cè)試數(shù)據(jù)庫(kù)為sql server,服務(wù)器為本機(jī),數(shù)據(jù)庫(kù)名為test,表名為a,兩個(gè)字段id(int)主鍵標(biāo)識(shí),num(int)
set conn=server.CreateObject("adodb.connection")
strConn="provider=sqloledb.1;persist security info=false;uid=sa;pwd=sa;Initial Catalog=test;Data Source=."
conn.Open strConn
'以上代碼建立數(shù)據(jù)庫(kù)連接
conn.BeginTrans '事務(wù)開(kāi)始
strSql1="update a set num=1000 where id=24" '第一個(gè)sql語(yǔ)句為update。(語(yǔ)法正確)
strSql2="insert into a(num) values('a')" '第二個(gè)sql語(yǔ)句為錯(cuò)誤的sql語(yǔ)句
strSql3="insert into a(num) values(33333)" '第三個(gè)sql語(yǔ)句為正確的sql語(yǔ)句
call conn.execute(strSql1)
call conn.execute(strSql2)
call conn.execute(strSql3)
if conn.Errors.Count=0 then
conn.CommitTrans '如果沒(méi)有conn錯(cuò)誤,則執(zhí)行事務(wù)提交
else
conn.RollbackTrans '否則回滾
end if
%>
以上代碼經(jīng)調(diào)試,可以正常的進(jìn)行事務(wù)處理。但是有時(shí)候,我們并不想將編譯錯(cuò)誤顯示給用戶(hù)。
則我們需要在conn.BeginTrans后面加上On error resume next
但是因?yàn)橛玫搅薕n error resume next。conn.Errors.Count只能獲得最后一個(gè)數(shù)據(jù)庫(kù)操作的conn返回的結(jié)果 。上面的三個(gè)sql語(yǔ)句,因?yàn)樽詈笠粋€(gè)sql語(yǔ)句是正確的,則此事務(wù)處理就無(wú)效了。那我們需要對(duì)出錯(cuò)處理作出相對(duì)應(yīng)的修改。
if conn.Errors.Count=0 then應(yīng)該改為if err.number=0 then
這樣,我們可以在數(shù)據(jù)庫(kù)回滾后同時(shí)做出其他相對(duì)應(yīng)的操作或者提示。修改后的代碼如下:
以下是引用片段:
<%
set conn=server.CreateObject("adodb.connection")
strConn="provider=sqloledb.1;persist security info=false;uid=sa;pwd=sa;Initial Catalog=test;Data Source=."
conn.Open strConn
'以上代碼建立數(shù)據(jù)庫(kù)連接
conn.BeginTrans '事務(wù)開(kāi)始
on error resume next '增加的代碼
strSql1="update a set num=1000 where id=24" '第一個(gè)sql語(yǔ)句為update。(語(yǔ)法正確)
strSql2="insert into a(num) values('a')" '第二個(gè)sql語(yǔ)句為錯(cuò)誤的sql語(yǔ)句
strSql3="insert into a(num) values(33333)" '第三個(gè)sql語(yǔ)句為正確的sql語(yǔ)句
call conn.execute(strSql1)
call conn.execute(strSql2)
call conn.execute(strSql3)
if err.number =0 then
conn.CommitTrans '如果沒(méi)有conn錯(cuò)誤,則執(zhí)行事務(wù)提交
else
conn.RollbackTrans '否則回滾
'回滾后的其他操作
strerr=err.Description
Response.Write "數(shù)據(jù)庫(kù)錯(cuò)誤!錯(cuò)誤日志:<font color=red>"&strerr &"</font>"
Response.End
end if
%>
1、將用戶(hù)信息記入數(shù)據(jù)庫(kù)
2、為用戶(hù)開(kāi)個(gè)文件夾用于存儲(chǔ)
3、初始化用戶(hù)操作日志
這三步必須使用事務(wù),否則萬(wàn)一磁盤(pán)操作失敗,而沒(méi)有撤銷(xiāo)數(shù)據(jù)庫(kù)操作,就會(huì)造成只能登陸而不能操作的“死用戶(hù)”現(xiàn)象。
由于數(shù)據(jù)庫(kù)系統(tǒng)特殊的發(fā)展歷史,小至Access,大到DB2,無(wú)不帶有事務(wù)支持。因此上述步驟可以如下表示:
以下是引用片段:
On Error Resume Next
第一步:
在事務(wù)環(huán)境下把用戶(hù)信息記入數(shù)據(jù)庫(kù)
If Err Then
關(guān)閉連接
退出
Else
第二步:創(chuàng)建文件夾
If Err Then
回滾第一步數(shù)據(jù)庫(kù)操作,退出
Else
第三步:在事務(wù)環(huán)境下操作日志數(shù)據(jù)庫(kù)
If Err Then
回滾第一步操作,刪除第二步建立的文件夾
退出
End If
End If
End If
提交第一步數(shù)據(jù)庫(kù)操作的事務(wù)
提交第二步數(shù)據(jù)庫(kù)操作的事務(wù)
End
每一步都需要進(jìn)行判斷,如果失敗,還需要手工回滾前面多步操作,使程序變得復(fù)雜、難懂。如果今后更新了程序,增加其他步驟,還需要嵌套更多層的If...Else...End If,使程序流程更加復(fù)雜。
正確的解決辦法是使用ASP的事務(wù)控制功能。IIS通過(guò)和MTS服務(wù)聯(lián)系,可以控制多種支持事務(wù)的系統(tǒng),當(dāng)程序發(fā)出“失敗”的信號(hào)時(shí),所有支持事務(wù)的系統(tǒng)均將自動(dòng)回滾,即使操作已經(jīng)正式完成;對(duì)不支持事務(wù)的操作也提供了方便的手工回滾方式。上面的例子用ASP事務(wù)控制功能重寫(xiě)如下:
復(fù)制代碼 代碼如下:
<%@ TRANSACTION = Required %>
On Error Resume Next
Set Conn=Server.CreateObject("ADODB.Connection")
Conn.Open ....
Conn.Execute "INSERT...."
Conn.Close
Set Conn=Nothing
Set Conn2=Server.CreateObject("ADODB.Connection")
Conn2.Open ....
Conn2.Execute "INSERT...."
Conn2.Close
Set Conn2=Nothing
Set FSO=Server.CreateObject("Scripting.FilesystemObject")
FSO.CreateFolder "...."
If Err Then
ObjectContext.SetAbort '通知所有支持事務(wù)的組件回滾,并運(yùn)行手工回滾代碼
Else
ObjectContext.SetComplete
End If
Set FSO=Nothing
Sub OnTransactionAbort
Response.Write "錯(cuò)誤"
FSO.DeleteFile Server.Mappath("a.txt") 'FSO的手工回滾——?jiǎng)h除文件夾
End Sub
Sub OnTransactionCommit
Response.Write "勝利完成任務(wù)"
End Sub
%>
第一行的<%@ TRANSACTION = Required %>表示這一頁(yè)ASP文件需要MTS的事務(wù)支持。中間的各個(gè)操作都按普通順序書(shū)寫(xiě),而不用考慮回滾問(wèn)題。在程序最后判斷是否有錯(cuò)誤。如果有,調(diào)用ObjectContext的SetAbort方法,IIS會(huì)通過(guò)MTS服務(wù)通知所有支持事務(wù)的組件回滾(主要是數(shù)據(jù)庫(kù)),并且運(yùn)行Sub OnTransactionAbort對(duì)不支持事務(wù)的操作手工回滾;如果沒(méi)有發(fā)生錯(cuò)誤,調(diào)用ObjectContext的SetComplete方法,則會(huì)運(yùn)行Sub OnTransactionCommit來(lái)顯示成功的消息。
整個(gè)ASP程序不需要為判斷錯(cuò)誤和回滾操作書(shū)寫(xiě)多余的代碼,只須在最后進(jìn)行判斷,即使今后增加了多步操作,也只需要在Sub OnTransactionAbort中進(jìn)行控制即可,非常方便,程序員可以專(zhuān)注于過(guò)程編寫(xiě)而不是書(shū)寫(xiě)糾錯(cuò)代碼。
其實(shí)ASP還提供了許多更有用的功能,等著我們使用,千萬(wàn)不要以為ASP使用腳本語(yǔ)言,功能就一定弱。
以下是引用片段:
<%
'asp事務(wù)處理。
'測(cè)試數(shù)據(jù)庫(kù)為sql server,服務(wù)器為本機(jī),數(shù)據(jù)庫(kù)名為test,表名為a,兩個(gè)字段id(int)主鍵標(biāo)識(shí),num(int)
set conn=server.CreateObject("adodb.connection")
strConn="provider=sqloledb.1;persist security info=false;uid=sa;pwd=sa;Initial Catalog=test;Data Source=."
conn.Open strConn
'以上代碼建立數(shù)據(jù)庫(kù)連接
conn.BeginTrans '事務(wù)開(kāi)始
strSql1="update a set num=1000 where id=24" '第一個(gè)sql語(yǔ)句為update。(語(yǔ)法正確)
strSql2="insert into a(num) values('a')" '第二個(gè)sql語(yǔ)句為錯(cuò)誤的sql語(yǔ)句
strSql3="insert into a(num) values(33333)" '第三個(gè)sql語(yǔ)句為正確的sql語(yǔ)句
call conn.execute(strSql1)
call conn.execute(strSql2)
call conn.execute(strSql3)
if conn.Errors.Count=0 then
conn.CommitTrans '如果沒(méi)有conn錯(cuò)誤,則執(zhí)行事務(wù)提交
else
conn.RollbackTrans '否則回滾
end if
%>
以上代碼經(jīng)調(diào)試,可以正常的進(jìn)行事務(wù)處理。但是有時(shí)候,我們并不想將編譯錯(cuò)誤顯示給用戶(hù)。
則我們需要在conn.BeginTrans后面加上On error resume next
但是因?yàn)橛玫搅薕n error resume next。conn.Errors.Count只能獲得最后一個(gè)數(shù)據(jù)庫(kù)操作的conn返回的結(jié)果 。上面的三個(gè)sql語(yǔ)句,因?yàn)樽詈笠粋€(gè)sql語(yǔ)句是正確的,則此事務(wù)處理就無(wú)效了。那我們需要對(duì)出錯(cuò)處理作出相對(duì)應(yīng)的修改。
if conn.Errors.Count=0 then應(yīng)該改為if err.number=0 then
這樣,我們可以在數(shù)據(jù)庫(kù)回滾后同時(shí)做出其他相對(duì)應(yīng)的操作或者提示。修改后的代碼如下:
以下是引用片段:
<%
set conn=server.CreateObject("adodb.connection")
strConn="provider=sqloledb.1;persist security info=false;uid=sa;pwd=sa;Initial Catalog=test;Data Source=."
conn.Open strConn
'以上代碼建立數(shù)據(jù)庫(kù)連接
conn.BeginTrans '事務(wù)開(kāi)始
on error resume next '增加的代碼
strSql1="update a set num=1000 where id=24" '第一個(gè)sql語(yǔ)句為update。(語(yǔ)法正確)
strSql2="insert into a(num) values('a')" '第二個(gè)sql語(yǔ)句為錯(cuò)誤的sql語(yǔ)句
strSql3="insert into a(num) values(33333)" '第三個(gè)sql語(yǔ)句為正確的sql語(yǔ)句
call conn.execute(strSql1)
call conn.execute(strSql2)
call conn.execute(strSql3)
if err.number =0 then
conn.CommitTrans '如果沒(méi)有conn錯(cuò)誤,則執(zhí)行事務(wù)提交
else
conn.RollbackTrans '否則回滾
'回滾后的其他操作
strerr=err.Description
Response.Write "數(shù)據(jù)庫(kù)錯(cuò)誤!錯(cuò)誤日志:<font color=red>"&strerr &"</font>"
Response.End
end if
%>
相關(guān)文章
ASP運(yùn)行出錯(cuò):缺少對(duì)象: ''xmlDoc.documentElement''錯(cuò)誤解決方法
ASP運(yùn)行出錯(cuò):缺少對(duì)象: 'xmlDoc.documentElement'錯(cuò)誤解決方法,需要的朋友可以參考下2012-03-03插件下載┊垃圾引用防御補(bǔ)?。啃r(shí)自動(dòng)換KEY,支持靜態(tài)頁(yè)面)
插件下載┊垃圾引用防御補(bǔ)丁(每小時(shí)自動(dòng)換KEY,支持靜態(tài)頁(yè)面)...2007-02-02防止網(wǎng)站被采集的理論分析以及十條方法對(duì)策
很多防采集方法在施行的時(shí)候需要考慮是否影響搜索引擎對(duì)網(wǎng)站的抓取,所以先來(lái)分析下一般采集器和搜索引擎爬蟲(chóng)采集有何不同。2009-04-04asp短信接口源碼 比較簡(jiǎn)單但也挺實(shí)用用的(兩個(gè)寫(xiě)法)
這是關(guān)于短信接口的一些調(diào)用方法,asp的,兩個(gè)方式,調(diào)用短信接口都比較簡(jiǎn)單,但也比較實(shí)用2012-01-01