Hello, after a certain time, i get: ISC ERROR MESSAGE: Unable to complete network request to host "xxx.xxx.xxx.xx". Error writing data to the connection. An existing connection was forcibly closed by the remote host.
I can only reboot the host-service, to fix this, but after some time this error comes again.
if pooled:= true or pooled:= false, makes no difference. Therefore i think, exsisting connections will not be valitaded, refused and recreated, if there is an error. I also tried to set: keepconnection:= true, but no success.
My question is now, how can i fix this, and on what place in the sourcecode i could implement my own dbpool (that valitidates the connecitons).
IBO has a function verifyconnection that results: false if, the connection is not connected, or/and set a "Connectionlost" flag, if an error like above receives. (function TIB_Connection.VerifyConnection: boolean)
1) Setting TTDIBODriver.Pooled = False, will destroy all current connections in the pool. Setting TTDIBODriver.Pooled = True, will recreate pooled connections.
2) So, you can try to change the TTDSQLDriver.InternalGetDataSet method to something like that:
procedure TTDSQLDriver.InternalGetDataSet(ADataSetKind: TTDDataSetKind;
AInfo: TTDRequestInfo);
var
iRetry: Integer;
begin
if Pooled then begin
iRetry := 0;
while True do
try
FPool.Acquire(AInfo.FDataSetHost);
try
(AInfo.FDataSetHost as ITDSQLDataSetHost).GetSQLDataSet(ADataSetKind, AInfo);
Break;
except
FPool.Release(AInfo.FDataSetHost);
raise;
end;
except
on E: EIBOException do
if (E means "connection is losted") and
(iRetry <= 1) then begin
Pooled := False;
Pooled := True;
Inc(iRetry);
end
else
raise;
end;
end
else
DoGetDataSet(ADataSetKind, AInfo);
if (AInfo.FDataSet <> nil) and Assigned(FAfterGetDataSet) then
FAfterGetDataSet(Self, AInfo.FDataSet);
end;
and it seems i have another version as you, but downloaded the last 1.3.1 two days before, look:
procedure TTDSQLDriver.InternalGetDataSet(ADataSetKind: TTDDataSetKind; var ADataSet: TDataSet; var ADBMSKind: TTDDBMSKind; var AParamMark: TTDParamMark; var ADataSetHost: IADStanObject); var iRetry :integer; begin if Pooled then begin iRetry := 0; while True do try FPool.Acquire(ADataSetHost); try (ADataSetHost as ITDSQLDataSetHost).GetSQLDataSet(ADataSetKind, ADataSet, ADBMSKind, AParamMark); Break; except FPool.Release(ADataSetHost); raise; end; except on E:Exception do if (iRetry <= 1) then begin xlog('Error> '#13#10+E.Message); Pooled := False; Pooled := True; Inc(iRetry); end else raise; end; end else DoGetDataSet(ADataSetKind, ADataSet, ADBMSKind, AParamMark); if (ADataSet <> nil) and Assigned(FAfterGetDataSet) then FAfterGetDataSet(Self, ADataSet); end;
BUT the error not here comes, it comes in: procedure TTDSQLProcessor.DoStartSelect(AInfo: TTDSelectInfo; var ADefaultAction: Boolean);
on line: oProv.PSSetParams(AInfo.Params);
please help, i wasted now two days without an result
if pooled:= true or pooled:= false, makes no difference. Therefore i think, exsisting connections will not be valitaded, refused and recreated, if there is an error.
Ok. I am not expert in IB/FB. But it looks like it is FB client failure. And it must be reinitialized. Probably, the best will be to resolve this issue, and not to fix ThinDAC. If you think, that is ThinDAC issue, then ...
I will suggest to add Driver.BeforeGetDataSet event. There you will need to check, if system is alive or not. If not, then you will need to set Driver.Pooled = False, reinitialize IB/FB client and set Driver.Pooled = True.
How to check is system alive or not ? Most simple will be to create connection to IB/FB. And to check it in BeforeGetDataSet calling VerifyConnection method.
Thank you very much Dmitry , your support was very helpfull and fixed my problem.
Using AfterGetDataSet event from TDIBODriver, where i could verify the connection and recreate, if neccessary.
procedure TDataModule_sql.TDIBODriver1AfterGetDataSet(ASender: TObject; ADataSet: TDataSet); var oDB: TIBODatabase; begin if ((TIBODataset(ADataSet).IB_Connection.VerifyConnection = false) or (TIBODataset(ADataSet).IB_Connection.ConnectionWasLost = true)) then begin TIBODataset(ADataSet).IB_Connection.Free;
oDB := TIBODatabase.Create(nil); if TDIBODriver1.DBServer <> '' then oDB.Server := TDIBODriver1.DBServer; if TDIBODriver1.DBPath <> '' then oDB.Path := TDIBODriver1.DBPath; if TDIBODriver1.DBUserName <> '' then oDB.Username := TDIBODriver1.DBUsername; if TDIBODriver1.DBPassword <> '' then oDB.Password := TDIBODriver1.DBPassword; if TDIBODriver1.DBCharset <> '' then oDB.CharSet := TDIBODriver1.DBCharSet; oDB.Protocol := TDIBODriver1.DBProtocol; oDB.SQLDialect := TDIBODriver1.DBSQLDialect; oDB.LoginPrompt := False; TIBODataset(ADataSet).IB_Connection := oDB; oDB.Connected := True; end; end;