我将ADOConnection.BeginTrans
ADOConnection.CommitTrans
ADOConnection.RollbackTrans
分别在三个函数中书写,然后在程序中使用此三个函数。望大家给予指正,谢谢
代码:
procedure sw_b;//开始事务
begin
  if SVRdm.sADOConn.ConnectionString<>'' then
  begin
    if SVRdm.sAdoconn.Connected=false then SVRdm.sAdoconn.Connected:=true;//重新连接到数据源
    SVRdm.sADOConn.BeginTrans;//开始一个事务
    if SVRdm.sADOConn.InTransaction<>true then //不为真时,表示没有活动事务
      begin
        messagebox(MYMSG('FUNCBeginTransERR'),0);//FUNCBeginTransERR=事务开始失败
        EXIT;
      end
  end
  else
  begin
    messagebox(MYMSG('FUNCconnstringisNULL'),0);//FUNCconnstringisNULL=连接字串为空
  end
end;procedure sw_C;//提交事务
begin  SVRdm.sADOConn.CommitTrans;
  if SVRdm.sADOConn.InTransaction<>false then//不为假时,表示还有活动事务
    begin
      messagebox(MYMSG('FUNCCommitTransERR'),0);//FUNCCommitTransERR=事务提交失败
      EXIT;
    end
   else
     begin
//       SVRdm.sAdoconn.Connected:=false;//正确操作后,关闭数所源
     end
end;procedure sw_R;//回滚事务
begin
  SVRdm.sADOConn.RollbackTrans;
  if SVRdm.sADOConn.InTransaction<>false then//不为假时,表示还有活动事务
    begin
      messagebox(MYMSG('FUNCRollbackTransERR'),0);//FUNCRollbackTransERR=事务回滚失败
      EXIT;
    end
  else
     begin
//       SVRdm.sAdoconn.Connected:=false; //正确操作后,关闭数所源
     end
end;调用例子:
       sw_b;
     if  sqlexec(0,'UPDATE 登录表 SET 状态=''ON'',计算机名='''+ComputerName+''' where 用户名='''+loginusename+'''')<0 then
        begin
         messagebox(MYMSG('FUNCupdateUsenameStatErr'),0);//FUNCupdateUsenameStatErr=更新用户信息失败,请检查。
         sw_r;
        end
     else
        begin
          sw_c;
        end;

解决方案 »

  1.   

    可以阿,最好的设计是声明一个DatabaseService接口,应用时调用这个接口,然后分别写出bde,ado...的实现,这样保证在数据连接变化时改动最小
      

  2.   

    to JavaD(一竿残照) :能告诉我如何声明DatabaseService接口吗?我不是很明白。没用这个它。谢谢
      

  3.   

    我看到其他的贴子中是这样写的。
    ADOConnection.BeginTrans
    try
      ...
      ADOConnection.CommitTrans
    except
      ADOConnection.RollbackTrans
    end;但我觉得对程序给维护带来了不便,不知道能否帮我纠正一下上面的函数,谢谢。
      

  4.   

    这样
    type 
      IDataService=interface
       procedure begintrans;
       procedure CommitTrans;
       procedure RollBackTrans;
      end;  TBdeDS = class(TInterfacedObject,IDataService)
       procedure begintrans;
       procedure CommitTrans;
       procedure RollBackTrans;
      end;    TAdoDS = class(TInterfacedObject,IDataService)
       procedure begintrans;
       procedure CommitTrans;
       procedure RollBackTrans;
      end;实现之...然后在应用的时候,你只需要根据你系统的访问特性来生成一个ds 例如
     MyDs := TAdoDs.Create;或者 MyDs:=TBdeDS.create;//需要修改的只是这句
    在你的应用中就可以
    MyDs.BeginTrans;
    ....
    MyDs.CommitTrans;  
    except
    MyDs.RollbackTrans;
      

  5.   


    MyDs.BeginTrans;
    ....
    MyDs.CommitTrans;  
    except
    MyDs.RollbackTrans;
    都不用改,并且比你封装的方法可以重用,简单说就是应用代码只需要一个IDataService接口就ok了,不管这个接口是bde还是ado提供的,也不需要让应用代码知道这些细节,
      

  6.   

    可还是要使用到try...except结构,我不太想用这种结构,我想在用条件判断的方法来实现事务的调用。不知道如何才好。真的感谢大家,如果能解决,就贴了。
    例如:
    sw_b;
         if  sqlexec(0,'UPDATE 登录表 SET 状态=''ON'',计算机名='''+ComputerName+''' where 用户名='''+loginusename+'''')<0 then
            begin
             messagebox(MYMSG('FUNCupdateUsenameStatErr'),0);//更新用户信息失败,请检查。
             sw_r;
            end
         else
            begin
              sw_c;
            end;
      

  7.   

    如果你不想充斥着try..except的化,就只能这样
    type TProc = procedure of Object; IDataServicePlus = interface(IDataService)
       procedure Update(UpdateProc:TProc );
     end; TBdeDs = class(TInterfacedobject,IDataservicePlus)
       procedure Update(UpdateProc:TProc );
     end; Txxx = class
     private
       procedure updateData;
       procedure doUpdateData;
     end;procedure TXxx.doUpdateData;
    begin
      Table1.Post;//可以有多行代码
    end;procedure TXxx.UpdateData;
    begin
      MyDs.update(doUpdateData);
    end;//必须将每个更新都封装在一个函数里,并将该函数传入DataService,用其服务来更新,但是这样感觉代码更麻烦了,不是吗?proceudre TBdeDs.Update(UpdateProc:TProc );
    begin
      Begintrans;
      try
        UpdateProc;
        CommitTrans;
      except
        RollbackTrans;
      end;    
    end;
      

  8.   

    这倒是,实现也比较困难。
    其实我的思路是这样的:
    1.在开始更新、删除、插入时就开始一个事务(ADOConnection.BeginTrans)
    2.判断SQL语句是否执行成功,如果成功则提交一个事务(ADOConnection.CommitTrans)
    3.反之则回滚一个事务(ADOConnection.RollbackTrans)注:判断SQL语句是否执行成功的函数代码:
    function sqlexec(openORExecSQL:integer;sqlstr:string):integer;//SQL语句执行函数
    {retuinfo 等于0时不返回结果集,大于0时,返回结果集
    sqlstr为要执行的SQL语句}
    begin
    {执行SQL语句}
      SVRdm.sCreadata.close; //关闭之前查询
      SVRdm.sCreadata.SQL.clear;//清空SQL语句
      try
         SVRdm.sCreadata.sql.Add(sqlstr);
         if openORExecSQL=0 then
           begin
             SVRdm.sCreadata.ExecSQL; //不返回结果集
           end
         else
           begin
              if not SVRdm.sCreadata.Prepared then  //当不为真时
                begin
                 SVRdm.sCreadata.Prepared:=true;  //为真时,为查询作第一次准备,以回快查询速度。
                 SVRdm.sCreadata.open; //返回结果集
                end
              else
                begin
                 SVRdm.sCreadata.open; //返回结果集
                end
           end;
         result:=1; //返回大于0的值
      except
         result:=-1; //当出现错误返回小于0的值
      end;
    end;
      

  9.   

    不知道事务处理时,是否一定会用到try...except这样的结构,我感到很迷惑,请大家给一个肯定的答复,谢谢。
      

  10.   

    如果你的更新都是用sql语句,而不是用组件的化,当然可以使用你所构想的机制了