同一个页面中,可能有许多操作,有时候要求这些操作要么都成功,要么都失败,比如数据库操作:向 A 表写数据,之后向 B 表写数据,如果向 B 表写数据失败后,就要撤销向 A 表写的数据。这就得依靠事件。SQL Server 等数据库管理系统中均有事务这一功能,不过这里说的是 ASP 的。
本文以数据库操作为例讲解 ASP 中的事务,但并不是说只有数据库操作才能使用事务,只要支持 ASP 事务接口的对象操作均是可以的。
从例子开始
首先建立一个 Access 数据库,表 tbl,字段 ID、fld,这两个字段均不允许重复值。现在表中有两条记录:
ID fld
1 1
2 2
现在的需求(需求有点 BT,不要太在意,只是演示)是:
- 把 ID 为 1 的 记录的 fld 值 +2;
- 然后把 ID 为 2 的记录的 fld 值 +1。
- 两个更新必须均成功,或均失败。
在没有事务的 ASP 代码中
执行:
conn.Execute "update tbl set fld=fld+2 where ID=1"
conn.Execute "update tbl set fld=fld+1 where ID=2"
第一句执行成功,第二句执行失败,因为两条记录的 fld 均是 3,出错了。最终的结果是第一条记录的 fld 变了,第二条记录的 fld 没变,与需求中的第三点不相符。
使用事务来解决
<%@ transaction=required %>
<%option explicit%>
<%
on error resume next
dim conn
set conn = Server.CreateObject("ADODB.Connection")
'conn.open "Provider=Microsoft.jet.oledb.4.0;data source=" & Server.MapPath("Trans.mdb") '事务时不能使用此驱动
conn.Open "Driver={Microsoft Access Driver (*.mdb)};DBQ= " & Server.MapPath("Trans.mdb")
conn.BeginTrans
conn.Execute "update tbl set fld=fld+2 where ID=1"
conn.Execute "update tbl set fld=fld+1 where ID=2"
if err.number = 0 then
conn.CommitTrans
conn.close()
set conn = nothing
else
conn.RollbackTrans
conn.close()
set conn = nothing
end if
%>
在执行第二句 sql 语句时,由于 fld 值重复,导致更新失败,此时 err.number <> 0,触发 conn.RollbackTrans,事务回滚,这样第一句 sql 所做的更新也被撤销了。
要点
- transacation 指令。
- 事务情况下,不能使用 Microsoft.jet.oledb.4.0 驱动。
- conn.BeginTrans 记录事务开始。
- conn.CommitTrans 提交事务,即认可事务中所做的更改。
- conn.RollbackTrans 回滚事务,即撤销事务中所做的更改。