三层服务器!到一个客户端在执行一个大的数据查询时!其它客户端就好像阻塞掉了!一定要等前一个查询完成后才能继续其它数据返回!(300分)

  • 主题发起人 主题发起人 qdyoung
  • 开始时间 开始时间
Q

qdyoung

Unregistered / Unconfirmed
GUEST, unregistred user!
来自:chinanbzxx, 时间:2003-4-28 17:01:00, ID:1810834 [显示:小字体 | 大字体]
http://www.delphibbs.com/delphibbs/dispq.asp?lid=1810834
确实如chinanbzxx所说存在排队现象,我用Ado做的中间层,
客户端专门做了一个测试程序,执行多个实例,都定时在同一个时间打开一个中间层的表,
返回所有数据,结果发现需要的最大时间与执行的实例数成正比,
很显然所有中间层是排队执行客户端请求的。
中间层用的是创建时默认的Multi Instance Apartment:
TComponentFactory.Create(ComServer, TTest,
Class_Test, ciMultiInstance, tmApartment);
有没有解决方法?
 
服務器的多線程是一個假像,你還需再加代碼才行。
 
加什么代码?
 
不会啊,我这边用得很好啊!客户端就是经常会死悼的问题一直得不到解决!
 
http://www.8421.org/work/testMidas.rar
是一个测试程序,首先运行服务器创建表并插入10000条记录
要求本机有sql server,sa用户没有密码,如果不是请修改程序
然后运行几个客户端,选择一个连接的服务器类型(使用不同线程模型的remote datamodule),然后都定在同一个时间启动执行调用服务器端接口获取所有10000条记录,看看所需要的时间是不是与客户端数量成正比,我这测试的每个客户端需要时间大概5s
目前客户端都都是通过socket connection连接到本机的服务器
 
多线程远程数据模块本身是没有问题的,问题在于访问数据模块上的数据元件时,
各个线程之间有没有阻塞。如果有,那么肯定要排队了。
阻塞的内容包括:信号灯、令牌锁。也许你自己没用它们,但数据组件却用了(例如
BDE、ADO的DATABASE、SESSION共用等)。如果你使用简单的CDS文件数据,肯定不会
阻塞。有些数据组件本身是不支持多线程共用的,它可能自己内部作了排队。甚至有
的数据组件没作同步,在多线程下会出错也不一定。
同样的数据库如ORACLE,你用ODBC、DOA、ADO、OCI,不同的组件可能对多线程的支
持都不一样,因此需要先了解它们的特性,才能决定是否使用多线程。
 
要加的代碼,就是李維的那本三層書上有說明。你可以找找
 
是的,李维的系统篇上分析过这种情况,这是由于一个apartment对多个com对象,虽然com对象是多线程的,但请求在apartment这里是排队的。
 
to: 迷糊,
我没有看过李维的相关章节,但是我的测试
表明显然没有排队,是同时执行的
to qdyoung,
你说的所用的总时间和客户端的数量成正比,并不能说明访问是被排队了的
因为,SQLServer插入数据的总速度是有限的,而且基本稳定的,
所以当有多个客户端时,每个客户端插入数据的时间就会加长,
不信,你可以写一个直接访问数据库,同时插入记录的小程序测试一下,
看看是不是插入的速度会和客户端的数量成反比呢?
看看我的测试,大家有什么启发
我用 ciMultiInstance, tmApartment 模式测试了一下,测试方法和结果如下:
实现应用服务器,定义方法 TestStr
function TDBSrv.TestStr: WideString;
var
s: String;
begin
s := IntToStr(GetTickCount);
Sleep(3000);
s := s + ',' + IntToStr(GetTickCount);
Sleep(2000);
s := s + ',' + IntToStr(GetTickCount);
Result := s;
end;

客户端调用的代码是:
procedure TForm1.Button1Click(Sender: TObject);
begin
DCOMConnection1.Connected := True;
Caption := DCOMConnection1.AppServer.TestStr;
DCOMConnection1.Connected := False;
end;

我先后启动了4个客户端,分别调用此函数,
结果如下(数字是自计算机启动以来的毫秒计数):
客户端1: 2556816,2559820,2561823
客户端2: 2557297,2560301,2562304
客户端3: 2557968,2560972,2562975
客户端4: 2558408,2561413,2563415
我们看到上面的时间点发生了严重的重叠,
所以得出结论:
ciMultiInstance, tmApartment 模式并不是排队处理的
而是同时为每个客户端服务的,
这种模式完全可以满足你的需要,
你所说的问题不是数据模块的线程模式造成的,
而是你的别的方面的设计有问题,
才造成了排队的现象(有可能是假排队现象)
 
我刚才也测试了一下,确实如 lich所言。但是李维老先生确实花了大量的篇幅解释ciMultiInstance, tmApartment模式是排队的,而且书上有他的测试抓图,好像也证据确凿。
迷糊ing。。。
 
搞不明白,但肯定只有一种答案,
而且帮助文件中对 Apartment 模式的说明和测试结果相符合
也或者是李老先生用的 Delphi 和我们的不太一样吧,
谁方便的话可以在其他的版本的Delphi上面测试一下,
我相信这个地方,Delphi应该不会有 Bug 的,毕竟是重要功能啊
 
我覺得還是換換聯接方式吧,比如用web或soap方式,可能會快很多。因為這種方式本來就庫多聯接而設置的。
 
我不太懂,不好意思!
 
...
Springson : 你说Web 和Soap会块吗? 我怎么就没觉得呢.相反是很慢呀!!??
 
tmApartment模式必须是进程内才管用
进程外一样是排队处理
 
to 南腔北调,
那您对我的测试结果如何看待呢?
你还是仔细看看帮助中对 tmApartment模式 的说明吧
 
to itren:
可能web和soap相對別的不是很快,但是它本來就是網頁和服務的方式,對於大量的用戶,大量的訪問,會有很好的控制。而別的可能就不大好。
 
嗯,我也希望你说的没错
但COM是MS的东东,我是看到有些书上在描述COM SERVER时,说到DELPHI的线程化模式与COM的线程支持有关,并且只适用于进程内服务器
帮助中对tmApartment模式的说明也不一定百分百的正确
 
李维在他的系统篇中开了一个玩笑,前边说Multi Instance Apartment是排队的,后边的解决方法中又说Multi Instance Apartment是多线程的。我事了一下,反正在 d5下如lich所言是同时执行的。
楼主的情况我觉得应该不是Multi Instance Apartment的问题,你看看com对象是不是用的同一个数据库连接
 
后退
顶部