hzb(Explorer) 是绝对的高手!

解决方案 »

  1.   

    抱歉,这几天比较忙,现在才给你回复。
    你的例子好像用到了CacheUpdate技术,如果需要转化到三层结构,可能需要传送客户端的Delta到服务端,由服务端更新(如果不用CacheUpdate,那将客户端的方法直接搬到服务端就是了)。
    如果你用的是MIDAS技术,就我所知,需要在服务端增加一个方法,由它进行事务处理,该方法如下:
    function TTransModule.DoTrans( vDelta1, vDelta2: OleVariant): WordBool;
    var
     n1,n2:integer;
    begin
     result:=true;
     Database1.Connected:=true;
     Database1.StartTransaction;
     try
      DataSetProvider1.ApplyUpdates(vDelta1,0,n1);
      DataSetProvider2.ApplyUpdates(vDelta2,0,n2);
     except
      DataBase1.Rollback;
      result:=false;
      Database1.Connected:=false;
      exit;
     end;
     if Database1.InTransaction
      then if ( (n1=0) and (n2=0)) then
       DataBase1.Commit 
      else begin 
        result:=false;
        DataBase1.Rollback; 
      end;
     Database1.Connected:=false;end;
    在这个例子中,DataSetProvider1连接Query1,DataSetProvider2连接Query2,他们的ResolveToDataSet设为true,否则数据更新时会调用Delphi本身的事务处理机制,造成错误。注意把Query1,Query2的RequestLive设为true,并且检查Query1,Query2,active时是否正常。
    这是用BDE的情况,如果你用ADO,那就使用ADO相应的事务处理语句。
    我定义了两个参数,第一个参数是DataSetProvider1对应的ClientDataSEt的Delta值,第二个参数是DataSetProvider2对应的ClientDataSEt的Delta值。在客户端则可以这样调用:
    procedure TForm1.Button3Click(Sender: TObject);
    begin
     SocketConnection1.Connected:=true;
     if
       SocketConnection1.AppServer.DoTrans(ClientDataSet1.Delta,ClientDataSet2.Delta)
     then begin
       ClientDataSet1.Reconcile(null);//清空Delta
       ClientDataSet2.Reconcile(null);//清空Delta
     end;
    end;如果你用的是MTS技术,那MTS本身就支持事务处理,你就编写三个组件,每个组件执行完以后SetComplete,或者SetAbort,那MTS自己处理事务的。
    这只是一个简单的例子,不够详细的地方请自己补充。如果有不明白的地方请看一下帮助,或者看一下李维的书,或者继续提问。Good luck.另外,需要更正一点,我可不是高手,我只是一个超级菜鸟而已,说不定你比我还高呢,大家互相学习吧。
      

  2.   

    Sorry,刚想起一个问题,如果用户没有修改任何数据就保存的话,用原来的语句会出错,因此请改成:
    procedure TForm1.Button3Click(Sender: TObject);
    var
     vdata1,vdata2:Olevariant;
    begin
     SocketConnection1.Connected:=true;
     vdata1:=ClientDataSet1.Delta;
     vdata2:=ClientDataSet2.Delta; if
       SocketConnection1.AppServer.DoTrans(vdata1,vdata2)
     then begin
       ClientDataSet1.Reconcile(null);//清空Delta
       ClientDataSet2.Reconcile(null);//清空Delta
     end;
    end;
      

  3.   

    hzb说的太好了!
    我有个简单的想法,你看行不行的通:
    在appserver端的datasetprovider1(连query1)的beforeapplyupdates事件中写
    Database1.StartTransaction;
    在datasetprovider2(连query2)的afterapplyupdates事件中写
    Database1.commit;
    在datasetprovider1和datasetprovider2的updataerror中写
    Database.Rollback;你看上面的方法行得通吗?
      

  4.   

      我用这种方法试了一下,在datasetprovider1(连query1)的beforeapplyupdates当中启动事务以后,在datasetprovider2(连query2)的afterapplyupdates当中,database.InTransaction已经是false,即已经不在事务状态,不知道在MIDAS内部什么地方终止了事务。并且,修改的数据也没有提交到数据库。
      当然你的办法也可能成功,只是我不知道应该如何做,或许你可以继续试验一下。如果有高手指点一下就更好了。
      

  5.   

    我试过了,不行,还是用hzb的方法试试吧。