中间层问题,请各位高手进来,谁能解决定当送足500分以上(300分)

  • 主题发起人 主题发起人 步步高
  • 开始时间 开始时间

步步高

Unregistered / Unconfirmed
GUEST, unregistred user!
dcom+bde+session+oracle(oracle8i+delphi5)
中间层分五个remotedatamodule
如果每个remotedatamodule各放一个database和一个session,那么程序运行稳定,但客户端
连接不能超过12个,超过12个中间层就会报‘too many session’错。
如果五个remotedatamodule都不放database 和session,而是在中间层的form上放置一个
database和一个session,五个remotedatamodule的数据集都连向form上的database和session
客户端连接上去了(48个),但中间层经常会莫名其妙的退出,而且毫无提示。
注(我中间层除五个remotedatabase,还挂了一个mts模块)
请各位高手指教
 
>>莫名其妙的退出
一般都是存在内存泄露导致的,你先下载个检测软件看看有没有内存没有释放
如Memory Sleuth, Memproof等等
 
設定BDE中的Configration/System/INIT的參數
 
把Tdatabase的HandleShared属性设为True.
 
session
可以不要呀,用它默认的试试呀
 
可能是没有共享Session的原因 >> 超过12个中间层就会报‘too many session’错。
我觉得如果访问一个库的话.不用这么麻烦吧!?
用一个就可以了!/ 至于为什么无法上去 48个点! 可能是没有做够的 Try finally..
有异常错误!
再问一句: 这是新做的还是应用过了?
(注:我用ADO 连接. Socket 连接方式)
 
我來了
先看看
 
我告訴你
中間層退出,很正常的....
 
你在實驗室?
 
前一種;
belong to 無狀態對象 + 連接池
配置問題........
第二種
belong to 有狀態對象,效率低,單線程

個人觀點
 
tdatabase.keepconnection :=false ?
 
不要用iprovider 接口
因為 use TMTSDataModule .
 
你的連接方式是甚麼?
 
解决方法如下:有任何不明白可发信到zqszf@21cn.com
定义Session缓冲池
PSessionPool = ^TSessionPool;
TSessionPool = record
Session : TSession;
InUsed : Boolean;
end;

TSessionPooler=class(TThreadList)
private
public
function GetIdleSession: TSession;
procedure ReleaseSession(SessionName: String);
end;

var
SessionPooler : TSessionPooler;
function TSessionPooler.GetIdleSession: TSession;
var i: Integer;
p: PSessionPool;
begin
Result := nil;
while Result=nildo
begin
Sleep(1);
with LockListdo
try
for i:=0 to Count-1do
begin
p := Items;
if not p^.InUsed then
begin
Result := p^.Session;
p^.InUsed := True;
Break;
end;
end;
finally
UnLockList;
end;
end;
end;

procedure TSessionPooler.ReleaseSession(SessionName: String);
var i: Integer;
p: PSessionPool;
begin
with LockListdo
try
for i:=0 to Count-1do
begin
p := Items;
if p^.Session.SessionName=SessionName then
begin
p^.InUsed := False;
Break;
end;
end;
finally
UnLockList;
end;
end;

procedure AddNewSession(Session: TSession);
var p: PSessionPool;
begin
if Assigned(SessionPooler) then
begin
New(p);
SessionPooler.Add(p);
p^.Session := Session;
p^.InUsed := False;
end else
raise Exception.Create('服务器缓冲池没有定义');
end;

生成足够的数据库连接
var aSen: TSession;
aDB: TDatabase;
for i:=1 to MaxSessiondo
//MaxSession自己定义,小于48
begin
aSen := Sessions.OpenSession(MultiSessionID + IntToStr(i));
AddNewSession(aSen);
aDb := TDatabase.Create(Self);
aDb.DriverName := 'MSSQL';//自己改
aDb.DatabaseName := myDatabaseName + IntToStr(i);
aDb.Params.Values['USER NAME'] := 'xxx';
aDb.Params.Values['PASSWORD'] := 'yyy';
aDb.SessionName := aSen.SessionName;
aDb.LoginPrompt := False;
aDb.KeepConnection := True;
end;

生成Session池实例
SessionPooler := TSessionPooler.Create;
每个TRemoteDataModule都重载Lock 和UnLock方法
TMyRemoteDBModule=class(TRemoteDataModule, IAppRModule)
private
aSession: TSession;
aDatabase: TDatabase;
public
procedure Lock;
override;
procedure Unlock;
override;
end;
procedure TMyRemoteDBModule.Lock;
var i: Integer;
begin
inherited;
aSession := SessionPooler.GetIdleSession;
aDatabase := aSession.Databases[0];
for i:=0 to ComponetCount-1do
if Componets is TDBDataSet then
begin
(Componets as TDBDataSet).SessionName := aSession.SessionName;
(Componets as TDBDataSet).DatabaseName := aDatabase.DatabaseName;
end;
end;

procedure TMyRemoteDBModule.UnLock;
begin

SessionPooler.ReleaseSession(aSession.SessionName);
inherited;
end;
 
設定BDE中的Configration/System/INIT的參數 按它的参数致少在5倍以上(512M)内存
算,把Tdatabase的HandleShared属性设为True.您现在应用层出现不正常退出,
就是线程冲突造成的。session起的作用就是在一个会话里只有一个线程。
它不会引起线程冲突。祝您好运。解决问题了,请回话。
 
谢谢大家,我会去试试
 
最好是用ADO连接。
 
后退
顶部