delphi三层应用经常死机(200分)

  • 主题发起人 主题发起人 zyhalj
  • 开始时间 开始时间
Z

zyhalj

Unregistered / Unconfirmed
GUEST, unregistred user!
有一个问题困扰了我一个多月,一直没有找出原因。面临的压力很大。肯请大师从百忙之中抽点时间帮我诊断一下。
具休情况如下:
我在拜读了你的大作《Delphi 5.x分布式多层就用--系统篇》和《Delphi 5.x ADO/MTS/COM+高级程序设计篇》以后, 采用MIDAS+COM技术开发了一套MRP系统。在开发阶断一切良好,等系统上线后,经常出现应用服务器无法响应客户端的请求,至使客户端象死机一样停在那里。
运行环境:
数据服务器和应用服务器共用一台 DELl PowerEdge 1600SC 服务器、WIN2000 Server、SQL Server 2000标准版,客户端:Windows 98。
开发技术:
应用服务器(NT服务模式):
通过ADOConnection与后台数据库连接。ADOQuery获取数据后经DataSetProvider传至客户端。对於Master/Detail类型的数据用《Delphi 5.x ADO/MTS/COM+高级程序设计篇》中第2章第2-3节介绍的方法。DataSetProvider的ResolveToDataSet=True,另外,在应用服务器中定义了五个方法:
function RegisterLog(const vUserId, vComputerId, vProgramId: WideString;
vOptType: Shortint;
const vKeyValues: WideString;
vOptTime:do
uble): OleVariant;
safecall;
--凳记操作日志
function UpDateUsedId(const vVoucherTable, vNowBillId: WideString;
vNowUsedId: Integer): OleVariant;
safecall;
--更新单据已用单号
procedure BegTrans;
safecall;
--启动事务
procedure ComTrans;
safecall;
--提交事务
procedure RobTrans;
safecall;
--回滚事务
客户端:
由TClientDataSet通过TDCOMConnection与应用服务器连接获取数据。客户端数据存盘时作了如下处理:
1)首先调用服务器中的BegTrans方法,
Try
2)调用服务器中的RegisterLog方法
3) TClientDataSet.ApplyUpdates(-1)方法
调用服务器中ComTrans方法
Except
调用服务器中RobTrans方法
end;

程序运行一段时间后(长短不定,有时3-4小时,有时1-2小时)应用服务器无法响应客户端请求,此时,只有将应用服务器服务停止,然后再启动服务,客户端方可正常运行。
一定请高手给解决帮忙呀
 
事务处理不当,应该是某个表被锁住了,死机的时候可以在服务器端查看SQL SERVER中有没有被锁住的表(sp_lock).
这种情况在单用户情况下一般不会发生,多用户情况下概率比较高
 
我提一个可能会出现的问题.
中间层不能用showmessage 或messagedlg 或 showmodal等函数.
 
还有啊.你做的这个系统好象被称为假三层吧.....哈....
最好不要把事务放在前端.. 怎么个事务最好放在中间层.
 
系统架构本来就有问题!李大侠的书可以用来学学但是用到实践中则不行...
 
事务应该封装到中间层才对啊,客户端只须传要保存的数据就行了,由中间层调用事务处理进行数据的保存过程。你这个架构在多用户时,会出现锁表的现象,可以尝试改改,呵呵。
 
有可能是MIDAS.dll的原因,注意更换啊
 
用事务解决
 
试一试客户端提交数据时用 TClientDataSet.ApplyUpdates(0) 控制客户端不允许出现错误
情况可能会好一些。
 
同意楼上
 
这中情况我也碰到过,做法跟楼主的差不多,
谁能给一个正确的三层示例程序看看呢?
E_Mail: Tang_717@163.com
万分感谢:
 
在服务器端,制作一个连接的客户端,可能问题就出在这里,我们以前遇到过这样的情况!
 
客户端不应该自己去使用事务,在中间层使用com+事务机制,通过setcomplete、setabort来控制事务,应该可以解决问题
 
事务不要由客户机控制!应该在服务端定义一个方法!把从客户端变化了的clientdata.delta进行更新!
http://www.delphibbs.com/delphibbs/dispq.asp?lid=2330434
尽量把服务端设计成[无状态]
李维的方法不一定对的!有时也要自己想!你可以改变一下设计思路!
模式我想应为:象浏览器和Web服务器一样!IE说白了!也是个瘦客户的应用程序啊!
你把应用端设计成象IE那样!服务端就象Web服务器样!不过过程有点复杂!
慢慢享受啦!
敬成各位高手指教!
 
1)检查网络是否稳定;
2)稳定->检查代码是否会有持续打开数据集的情况,如 open 后,数据获得完毕后,未关闭数据集,最常见的情况是:打开数据集后在一个DBGRID内直接修改数据。如果此时有另一个用户也打开此数据集时,必出错!同时,建议所有的insert、delete、updata等无返回结果的操作,后面紧跟一个commit。
 
这种现象的一种可能原因,是你的APP SERVER出现了需要你的鼠标去点掉的错误提示,就等在那里了。
而在NT服务模式下,你又看不到界面,看不到那个错误提示!
所以,做中间层,最好所有可能出错的地方都用try except包住!否则,只要一有错误弹出来,你就死了。
另外一种类似的情况就是楼上说的:
来自:caihua, 时间:2004-2-2 20:00:00, ID:2432255
我提一个可能会出现的问题.
中间层不能用showmessage 或messagedlg 或 showmodal等函数.
 
1)是不是你的数据有问题,TClientDataSet.ApplyUpdates(-1)把参数改为0试试;
2)是不是你每次都从服务器下载所有数据;如果是把它改为每次下载<100条试试;
 
to zyhalj
看了你的说明,什么错不敢妄下结论,给一建议
请用 TSocketConnection 替换 TDComConnection ,保证你马上知道是什么原因死的机。
 
问题有可能出现在客户端程序。
BegTrans;
事务开始;
处理事务
if 成功 then

ComTrans;
--提交事务
else

RobTrans;
--回滚事务
如果事务处理出现异常则既没提交又没回滚,这样肯定死机了。看看有没有这种可能。如果有应该加上异常处理。
BegTrans;
事务开始;
try
处理事务
if 成功 then

ComTrans;
--提交事务
else

RobTrans;
--回滚事务
except
RobTrans;
--回滚事务
end;
 
后退
顶部