抱歉,这几天比较忙,现在才给你回复。 你的例子好像用到了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.另外,需要更正一点,我可不是高手,我只是一个超级菜鸟而已,说不定你比我还高呢,大家互相学习吧。
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;
你的例子好像用到了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.另外,需要更正一点,我可不是高手,我只是一个超级菜鸟而已,说不定你比我还高呢,大家互相学习吧。
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;
我有个简单的想法,你看行不行的通:
在appserver端的datasetprovider1(连query1)的beforeapplyupdates事件中写
Database1.StartTransaction;
在datasetprovider2(连query2)的afterapplyupdates事件中写
Database1.commit;
在datasetprovider1和datasetprovider2的updataerror中写
Database.Rollback;你看上面的方法行得通吗?
当然你的办法也可能成功,只是我不知道应该如何做,或许你可以继续试验一下。如果有高手指点一下就更好了。