如何用delphi,在三层结构中实现事务处理。(200分)

在D5中处理事务时,已经不需要像c/s中用commit、rollback,因为
在D5中,当客户端调用applyupdates时,就进入数据更新过程。
当应用程序服务器的tdatasetprovider收到客户端的调用时,在开始
更新数据库之中的数据时,应用程序服务器便会开始进入交易控制的状态。
当更新成功时,它会自动调用commit;当发生错误时,就会调用rollback.
然后调用onreconcileerror找出失败的原因。
 
to zypany你说的这种情况,是你在用嵌套表或非主细下,才可以不用自己commit
 
我找遍了Delphi5的help,上面只提到DataSetProvider有自动事务处理机制,
然后就直接提到MTS可处理事务。正如ouke说的,有些情况下DataSetProvider
的自动事务处理机制是不适合的,灵活的事务处理支持在稍微复杂的应用中是
必然的要求,那怕是在服务端能实现也行。
在李维《Delphi5.x分布式多层应用系统篇》中也只提到MTS和CORBA能处理事务,
压根就不提DCOM,难道DCOM没有灵活处理事务的机制吗?愿闻其详。
 
dsm2000你说的“在一个客户端连接时可以实现事务,但多个客户端连接时,若同时
StartTransaction,就会报错”, 我试验过了,没有报错呀。
可能你没用session.
 
查看Delphi 4的provider.pas中,只在事务开始设datamark,结束时回datamark,
并没有与数据库项链,没有使用事务。对主从表也是这样,所以我用datarequest来
实现事务:
function Tqcdb.mat_inProviderDataRequest(Sender: TObject;
Input: OleVariant): OleVariant;
var
errcount:integer;
save: OleVariant;
begin
save:=input;
with qcdatabase,sender as Tproviderdo
begin
starttransaction;
try
result:=applyupdates(input,-1,errcount);
if(errcount>0)then
begin
rollback;
// result:=save;
exit;
end;
commit;
except
rollback;
end;
end;
end;
愿与大家共同讨论。
 
ouke的答案我很感兴趣,我确实没用session。
不知是怎样用呢?请具体一点。最好贴上源程序,谢谢!
 
我说的是Tsession控件。在服务器的RemoteDataModal加一个Tsession控件。TdataBase的sessionname的属性指向它,Tquery的sessionname的属性也指向它。
用Tsession的好处是,每一个用户都有自己的session连接。这样就可以同时提交
事务了。Tdatabase的handleshared.就可以设为false了
还有,你d5的补丁打了吗?
 
ouke:
d5的补丁都解决什么问题?我去borland的站点上没下到,方便的话能不能给我
发一份(Enterprise版):soulstar@sina.com
 
ouke:
你这种方法确实能实现事务,但是要求每个客户端都有独立的连接Session,
这样对服务器的资源要求是否过高?另外,李维书上说,这样受制于一台应用
程序服务器能够同时开启的Session的数目,而这个数目是BDE/IDAPI的限制。
考虑到可能用在WEB上,连接数目不应受限制。请问有没有一种两全其美的办法,
既能实现事务,连接数又无限(或足够多),更重要的是服务器资源是有限的。
嘿嘿,是否过于贪心,无奈中Delphi的毒瘾,欲罢不能,只好请老哥帮忙解馋咯。
拜托!拜托!^o^
 
恩,我想你还是没打补丁的原因,因为我在用户用同一个session时,也没出问题。
补丁解决了好多错误,在没打之前,简直不能编三层。
好大28兆呢。
www.inprise.com/devsupport/delphi/downloads/dent501download.html
可以下载
 
可以在appserver端
添加方法,供客户端调用,把修改的clientdataset.data通过
参数形式传递到appserver,在appserver中控制事务。
 
ouke:
我早就打过补丁了,我觉得这是用session的原理造成的,要想客户端连接之间互不影响,就要用独立的连接session,这必然就引起对session数目的限制和对服务器资源的要求,是鱼与熊掌的问题,同意吗?
somis:
您提供的方法我也试过,其实在客户端要求连接数据库的时候,appserver也得先建立session连接,一切与数据库的交互也是通过这个session来完成,所以要想在appserver中控制事务,也必须使各个连接session独立,问题同样归结到“对session数目的限制和对服务器资源的要求”。
 
dsm2000.我用事务没有问题。我怀疑你的rollback有问题,是不是事务根本就每滚
回。要不你跟踪一下后台?
 
ouke:
我想你没明白我的意思。我用您提供的办法确实能实现事务处理,多客户连接
情况也试过,没问题,谢谢。但这种办法会带出另外的问题(前面有较详细叙述)。
我想问的是:是否有一种两全其美的办法,既能实现事务处理,又不受session数
量的限制和服务器资源要求不会太高。
 
恩,如果你想要用在web上,那么就不要走BDE.的确会有限制。
我把要用在web上的一般用Ado 控件
 
在服务端使用Tdatabase,Tsession,Tporivder,Tquery类,客户端使用Tclientdatabase,Tdcomconnection,Tsource可以很容易实现的。
 
将ClientDataSet的Delta属性通过Dcom传给应用服务器端,应用服务器的DataBase
控制事务。并将数据更新回数据库。
for example
应用层:
Dcomconnection1.AppServer.Applupdates( cdsOrder.Delta , cdsCustomer.Delta );
中间层:
try
DataBase1.StartTransaction;
DataSetProvider1.ApplyUpdates( OrderDelta , MaxError ,ErrorCount );
if ErrorCount > 0 then
raise EDataBaseError.Create('error');
DataSetProvider2.ApplyUpdates( CustomerDelta, MxError
,ErrorCount );
if ErrorCount > 0 then
raise EDataBaseError.Create('error');
DataBase1.commit;
except
DataBase1.Rollback;
end;
 
多人接受答案了。
 
顶部