Subject | dbpool - multithreaded - Firebird 1.5.5 - IBObjects |
---|---|
Author | prom_prometheus |
Post date | 2008-01-13T11:48:29Z |
hello,
I try since a time to integrate a dbpool in a multithreaded server
application. All my tryings ended with this errormessages:
------------------------------------------------------------
ISC ERROR MESSAGE:
Error reading data from the connection.
STATEMENT:
TIBOInternalDataset: "<TIBOQuery>.<TIBOInternalDataset>."
------------------------------------------------------------
Maybe i make an essentional error, but i know not where.
My last version of the dbpool:
------------------------------------------------------------
//create a new DBConn:
function TFbDBPool.NewDBConn:TIB_Connection;
begin
CS.Enter;
try
Result:= TIB_Connection.Create(nil);
try
with Result do begin
result.DefaultTransaction:= TIB_transaction.create(nil);
defaulttransaction.ib_connection:= result;
defaulttransaction.autocommit:= true;
Server:= db_server;
Path:= db_path;
CharSet:= db_charset;
Username:= db_UserName;
Password:= db_Password;
result.Protocol:= cpTCP_IP;
keepconnection:= true;
sqldialect:= db_sqldialect;
connect;
end;
except
on E:Exception do begin
xLog('ERROR:DBPOOL:'#13#10+E.Message);
FreeDBConn(result);
raise;
end;
end;
finally
CS.Leave;
end;
end;
//destroy existing connection
procedure TFbDBPool.FreeDBConn(var conn:TIB_Connection);
begin
try
conn.ForceDisconnect;
except end;
try
freeandnil(conn);
except end;
end;
function TFbDBPool.GetDBConn:TIB_Connection;
begin
Result:=nil;
CS.Enter; //Criticalsection
try
if length(myPool) > 0 then begin
Result:= myPool[ length(myPool)-1 ];
SetLength(myPool, length(myPool)-1 );
end;
finally
CS.Leave;
end;
if result <> nil then begin //check of conn is okay
try
if result.ConnectionWasLost then
FreeDBConn(result)
else if not result.VerifyConnection then
FreeDBConn(result);
except
FreeDBConn(result);
end;
end;
if result = nil then Result:= NewDBConn; //if not okay create a new
end;
//after usage give conn back in the pool, if there was an error in
//usage, destroy this connection, drop:= true
procedure TFbDBPool.PutDBConn(conn:TIB_Connection; drop:boolean);
begin
if not drop then
begin
CS.Enter;
try
SetLength(mypool, length(mypool)+1);
mypool[length(mypool)-1]:=conn;
finally
CS.Leave;
end;
end else
FreeDBConn(conn);
end;
---------------------------------------------------------------------
Usage in a thread like this:
var
dbo :TIB_Connection;
q :TIBOQuery;
is_error:boolean;
begin
is_error:= true;
try
dbo:= dbpool.GetDBConn;
try
q:= TIBOQuery.create(nil);
try
q.IB_Connection:= dbo;
try
with q do begin
........
close;
end;
except
raise;
end;
finally
freeandnil(q);
end;
is_error:= false;
finally
putDBConn(dbo, is_error);
end;
end;
end;
---------------------------------------------------------------------
This works good for some minutes with 100ts of usings,
but then the error (see above) happens and increses.
Any idea is wellcome to avoid this error.
best regards
Gerhard
I try since a time to integrate a dbpool in a multithreaded server
application. All my tryings ended with this errormessages:
------------------------------------------------------------
ISC ERROR MESSAGE:
Error reading data from the connection.
STATEMENT:
TIBOInternalDataset: "<TIBOQuery>.<TIBOInternalDataset>."
------------------------------------------------------------
Maybe i make an essentional error, but i know not where.
My last version of the dbpool:
------------------------------------------------------------
//create a new DBConn:
function TFbDBPool.NewDBConn:TIB_Connection;
begin
CS.Enter;
try
Result:= TIB_Connection.Create(nil);
try
with Result do begin
result.DefaultTransaction:= TIB_transaction.create(nil);
defaulttransaction.ib_connection:= result;
defaulttransaction.autocommit:= true;
Server:= db_server;
Path:= db_path;
CharSet:= db_charset;
Username:= db_UserName;
Password:= db_Password;
result.Protocol:= cpTCP_IP;
keepconnection:= true;
sqldialect:= db_sqldialect;
connect;
end;
except
on E:Exception do begin
xLog('ERROR:DBPOOL:'#13#10+E.Message);
FreeDBConn(result);
raise;
end;
end;
finally
CS.Leave;
end;
end;
//destroy existing connection
procedure TFbDBPool.FreeDBConn(var conn:TIB_Connection);
begin
try
conn.ForceDisconnect;
except end;
try
freeandnil(conn);
except end;
end;
function TFbDBPool.GetDBConn:TIB_Connection;
begin
Result:=nil;
CS.Enter; //Criticalsection
try
if length(myPool) > 0 then begin
Result:= myPool[ length(myPool)-1 ];
SetLength(myPool, length(myPool)-1 );
end;
finally
CS.Leave;
end;
if result <> nil then begin //check of conn is okay
try
if result.ConnectionWasLost then
FreeDBConn(result)
else if not result.VerifyConnection then
FreeDBConn(result);
except
FreeDBConn(result);
end;
end;
if result = nil then Result:= NewDBConn; //if not okay create a new
end;
//after usage give conn back in the pool, if there was an error in
//usage, destroy this connection, drop:= true
procedure TFbDBPool.PutDBConn(conn:TIB_Connection; drop:boolean);
begin
if not drop then
begin
CS.Enter;
try
SetLength(mypool, length(mypool)+1);
mypool[length(mypool)-1]:=conn;
finally
CS.Leave;
end;
end else
FreeDBConn(conn);
end;
---------------------------------------------------------------------
Usage in a thread like this:
var
dbo :TIB_Connection;
q :TIBOQuery;
is_error:boolean;
begin
is_error:= true;
try
dbo:= dbpool.GetDBConn;
try
q:= TIBOQuery.create(nil);
try
q.IB_Connection:= dbo;
try
with q do begin
........
close;
end;
except
raise;
end;
finally
freeandnil(q);
end;
is_error:= false;
finally
putDBConn(dbo, is_error);
end;
end;
end;
---------------------------------------------------------------------
This works good for some minutes with 100ts of usings,
but then the error (see above) happens and increses.
Any idea is wellcome to avoid this error.
best regards
Gerhard