• ASP事物处理的实现方法


    一、SQL Server联机丛书中关于事务的定义

    事务
    事务是作为单个逻辑工作单元执行的一系列操作。一个逻辑工作单元必须有四个属性,称为 ACID(原子性、一致性、隔离性和持久性)属性,只有这样才能成为一个事务:
    原子性
    事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。

    一致性
    事务在完成时,必须使所有的数据都保持一致状态。在相关数据库中,所有规则都必须应用于事务的修改,以保持所有数据的完整性。事务结束时,所有的内部数据结构(如 B 树索引或双向链表)都必须是正确的。

    隔离性
    由并发事务所作的修改必须与任何其它并发事务所作的修改隔离。事务查看数据时数据所处的状态,要么是另一并发事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看中间状态的数据。这称为可串行性,因为它能够重新装载起始数据,并且重播一系列事务,以使数据结束时的状态与原始事务执行的状态相同。

    持久性
    事务完成之后,它对于系统的影响是永久性的。该修改即使出现系统故障也将一直保持。

    指定和强制事务处理
    SQL 程序员要负责启动和结束事务,同时强制保持数据的逻辑一致性。程序员必须定义数据修改的顺序,使数据相对于其组织的业务规则保持一致。然后,程序员将这些修改语句包括到一个事务中,使 Microsoft® SQL Server™ 能够强制该事务的物理完整性。

    企业数据库系统(如 SQL Server)有责任提供一种机制,保证每个事务物理的完整性。SQL Server 提供:

    锁定设备,使事务相互隔离。

    记录设备,保证事务的持久性。即使服务器硬件、操作系统或 SQL Server 自身出现故障,SQL Server 也可以在重新启动时使用事务日志,将所有未完成的事务自动地回滚到系统出现故障的位置。

    事务管理特性,强制保持事务的原子性和一致性。事务启动之后,就必须成功完成,否则 SQL Server 将撤消该事务启动之后对数据所作的所有修改。

    二、实例

    ①、利用ASP内置ADO组件中的Connection对象可以实现对数据库操作的事务性处理。
    Connection 对象中的事务进程:

    •BeginTrans - 开始新事务。

    •CommitTrans - 保存任何更改并结束当前事务。它也可能启动新事务。

    •RollbackTrans - 取消当前事务中所作的任何更改并结束事务。它也可能启动新事务。

     1  <%
     2 Call DBConnection(objConn)'//链接数据库
     3 On Error Resume Next
     4 
     5  objConn.BeginTrans    '//启动一个事务
     6 
     7 '//语句一
     8 strSql = "Insert Into  [User] (UName, UPasswd) Values ('"& s_uname &"', '"& s_upasswd &"')"
     9 objConn.Execute(strSql)
    10 '//语句二
    11 strSql = "Insert Into UserInfo (UName, Age, Sex, TelPhone, Address) Values ('"& s_uname &"', "& i_age &", '"& s_sex &"', '"& s_telphone &"', '"& s_address &"')"
    12 objConn.Execute(strSql)
    13 
    14  If objConn.Errors.Count Then
    15      Errors.Clear
    16      objConn.RollBackTrans'//如果有错误,则事务向前回滚
    17     Response.Write("Fail")
    18  Else
    19      objConn.CommitTrans    '//提交一个事务
    20     Response.Write("OK")
    21  End If
    22 
    23  Call DBClose(objConn)'//释放数据库链接
    24 %>

    注意:
    以上代码在语句一遇到错误时将不能进行正常的事务处理,语句一将得不到执行。因为用到了On Error Resume Next所以objConn.Errors.Count只能获得最后一个数据库操作的objConn返回的结果,但是因为语句二是正确的,所以此事务处理就无效了。那么就需要对出错处理作出相对应的修改。
    将If objConn.Errors.Count Then改为If Err Then

    ②、利用数据库系统自身的事务处理机制,通过在数据库服务器中编写包含事务的存储过程,完成对数据操作的事务处理。同时,利用ADO组件调用存储过程,根据存储过程的返回代码判断事务处理是否执行成功。

    在数据库系统中,每一条SQL语句都是一个事务。因此可以保证每条语句要么完成,要么退回到开始之处。但是如果希望一组SQL语句的操作要么全部完成,要么全部无效,就需要利用数据库的事务处理机制来实现。

    在数据库中生成存储过程的主要代码如下:

     1  CREATE Procedure dbo.RegisterUser
     2      @UName varchar(30),
     3      @UPasswd varchar(30),
     4      @Age Int,
     5      @Sex varchar(6),
     6      @TelPhone varchar(20),
     7      @Address varchar(50)
     8  as
     9  Set nocount ON
    10  Begin
    11      Begin Transaction
    12      Insert Into dbo.[User] (UName, UPasswd) Values (@UName, @UPasswd)
    13      If @@Error <> 0
    14          Begin
    15          /*操作失败,事务回滚*/
    16          RollBack Transaction
    17          /*返回存储过程,并设置返回码为事务操作失败*/
    18          Return -1
    19      End
    20      Insert Into dbo.[UserInfo] (UName, Age, Sex, TelPhone, Address) Values (@UName, @Age, @Sex, @TelPhone, @Address)
    21      If @@Error <> 0
    22          Begin
    23          /*操作失败,事务回滚*/
    24          RollBack Transaction
    25          Return -1
    26      End
    27      /*如果操作执行正确,则提交事务*/
    28      Commit Transaction
    29      Return 0
    30  End
    31  GO

    在ASP脚本中调用数据库存储过程的主要代码如下:

     1  Call DBConnection(objConn)'//链接数据库
     2 
     3 Set MyComm = Server.CreateObject("ADODB.Command")
     4  MyComm.ActiveConnection = objConn          'objConn是数据库连接对象
     5 MyComm.CommandText      = "RegisterUser"     '指定存储过程名
     6 MyComm.CommandType      = 4                 '表明这是一个存储过程
     7 MyComm.Prepared         = True              '要求将SQL命令先行编译
     8 
     9 '声明存储过程返回值
    10 MyComm.Parameters.Append MyComm.CreateParameter("RetCode",2,4)
    11 '//创建存储过程输入参数对象
    12 MyComm.Parameters.append MyComm.CreateParameter("@UName",200,1,30,s_uname)
    13  MyComm.Parameters.append MyComm.CreateParameter("@UPasswd",200,1,30,s_upasswd)
    14  MyComm.Parameters.append MyComm.CreateParameter("@Age",3,1,4,i_age)
    15  MyComm.Parameters.append MyComm.CreateParameter("@Sex",200,1,6,i_sex)
    16  MyComm.Parameters.append MyComm.CreateParameter("@TelPhone",200,1,20,s_telphone)
    17  MyComm.Parameters.append MyComm.CreateParameter("@Address",200,1,50,s_address)
    18  MyComm.Execute
    19 
    20  RetValue = CInt(MyComm("RetCode"))
    21 '//根据返回值判断注册是否成功
    22 If RetValue < 0 Then
    23      Response.Write("Fail")
    24  Else
    25      Response.Write("OK")
    26  End If
    27 
    28  Set MyComm = Nothing
    29  Call DBClose(objConn)'//释放数据库链接

    ③、利用MTS(Microsoft Transaction Server)组件的事务处理机制实现事务处理时,需要特别注意的是,这种机制下的事务不能跨越多个ASP页,如果一个事务处理需要来自多个组件的对象,则须将对这些对象的操作组合在一个ASP页中。

    首先需要在页首添加指令@TRANSACTION,将一个ASP页面声明为事务性。

    @TRANSACTION指令必须在一页中的第一行,否则将产生错误。当页面中ASP脚本处理结束时,当前事务即告结束。

     1  <%@Transaction = "Required" Language="VBScript"%>
     2  <%
     3  On Error Resume Next
     4 '//事务执行成功触发事件 
     5 Sub OnTransactionCommit()
     6      Response.Write("OK")
     7  End Sub
     8 
     9 '//事务执行失败触发事件 
    10 Sub OnTransactionAbort()
    11      Response.Write("Fail")
    12  End Sub
    13 
    14  Call DBConnection(objConn)'//链接数据库
    15 
    16 strSql = "Insert Into [User] (UName, UPasswd) Values ('"& s_uname &"', '"& s_upasswd &"')"
    17 objConn.Execute(strSql)
    18  strSql = "Insert Into UserInfo (UName, Age, Sex, TelPhone, Address) Values ('"& s_uname &"', "& i_age &", '"& s_sex &"', '"& s_telphone &"', '"& s_address &"')"
    19 objConn.Execute(strSql)
    20 
    21  If Err Then
    22      Err.Clear
    23      ObjectContext.SetAbort()
    24  Else
    25      ObjectContext.SetComplete()
    26  End If
    27 
    28  Call DBClose(objConn)'//释放数据库链接
    29 %>

    方案比较 :
    从灵活的角度考虑,选择采用ASP数据库组件的方法具有一定的优势:既可以选用ADO数据库组件完成事务处理,同时还可以根据实际需要,定制自己的数据库组件(只要满足ASP组件编写规范即可)。
    如果从数据库事务处理的可靠性等角度考虑,则采用数据库内部的事务处理存储过程更好。这样可以直接利用数据库事务机制完成应用程序的逻辑事务处理,安全可靠,并且减少了Web服务器与数据库服务器之间的数据交互。这一点对分布式数据库系统尤为重要。
    采用MTS组件的事务处理方法的优势在于:由MTS服务器直接控制和管理组件(在MTS中注册的组件)操作的完成和撤消,具有良好的扩展空间和应用前景,可以充分发挥MTS的技术优势,增强网络应用的容错性能,提高IIS Web服务器的动态性能。

  • 相关阅读:
    GJM :动作手游实时PVP 帧同步(客户端)[转载]
    GJM :多人在线游戏的设计思路
    GJM : 中断被Socket.Accept阻塞的线程
    GJM :异步Socket [转载]
    GJM :C#开发 异步处理是目的,多线程是手段
    GJM : FlatBuffers 与 protobuf 性能比较 [转载 ]
    GJM : Protobuf -NET 相比Json 传输速度只需要1/3 解析只需要1/10
    GJM : Unity3D结合ZXING制作二维码识别
    GJM : Unity3D 常用网络框架与实战解析 【笔记】
    javascripct数组
  • 原文地址:https://www.cnblogs.com/webczw/p/3380656.html
Copyright © 2020-2023  润新知