我使用Recovering Connection (FireDAC)中所述的Firedac连接恢复功能,并且在Delphi XE5上一切正常。
我安装了Delphi社区版本10.2、10.3和10.3.1进行迁移测试,发现数据库重新连接功能无法正常工作。
使用场景:
重现此问题的步骤:
1-创建一个新的VCL应用程序;
2-在Form1上,删除组件TFDConnection,TFDPhysPgDriverLink,TFDGUIxWaitCursor,TFDQuery和TButton;
3-为TFDPhysPgDriverLink的PostgreSQL和vendorlib libpq.dll的连接参数配置TFDConnection;
4-按照Recovering Connection (FireDAC)中的说明配置TFDConnection;
5-在TButton OnClick事件中,放置以下内容:
qry1.Close;
qry1.Open ('select 1');
6-在Recovering Connection (FireDAC)中所述,在TFDConnection的OnRecover事件中放置以下代码:
var
iRes: Integer;
begin
iRes: = MessageDlg ('Connection is lost. Offline - yes, Retry - ok, Fail - Cancel', mtConfirmation, [mbYes, mbOK, mbCancel], 0);
case iRes of
mrYes: AAction: = faOfflineAbort;
mrOk: AAction: = faRetry;
mrCancel: AAction: = faFail;
end;
// Log ('Connection is recovering');
7-运行应用程序;
8-单击一次TButton;
9-重新启动PostgreSQL服务或禁用/重新启用网络适配器;
10-再次单击TButton,请注意TFDConnection组件未触发OnRecover事件,而是显示以下错误:
[FireDAC] [Phys] [PG] [libpq]服务器关闭了连接 意外地这可能意味着服务器异常终止 在处理请求之前或期间。
再次单击TButton,每次都会显示另一个错误:
[FireDAC] [Phys] [PG] [libpq]与服务器无连接
预先感谢您对此进行审查。
这个问题与我的情况相似,但它是针对Delphi 10: When PostgreSQL stops TFDConnection.Connected remains True
答案 0 :(得分:0)
我根据RSP-23958向Embarcadero质量中心报告了此问题,并且对该错误进行了认可。有人叫德米特里(Dmitry)回答说,该问题将在Delphi 10.3的更新2中解决。
在RSP-23958中,附带了一个解决问题的修补程序,如果您具有带有Firedac源代码的Dephi,而未发布Delphi 10.3更新2,则可以使用它。
解决方法如下:
Index: runtime/data/firedac/FireDAC.Phys.PGWrapper.pas
===================================================================
--- runtime/data/firedac/FireDAC.Phys.PGWrapper.pas (revision 95224)
+++ runtime/data/firedac/FireDAC.Phys.PGWrapper.pas (revision 95225)
@@ -1109,7 +1109,9 @@
FDStrLike(sLCMessage, 'password authentication failed for user "%"') then
eKind := ekUserPwdInvalid
else if (Pos('connection refused', sLCMessage) <> 0) or
- (Pos('could not connect to server', sLCMessage) <> 0) then
+ (Pos('could not connect to server', sLCMessage) <> 0) or
+ (Pos('server closed the connection unexpectedly', sLCMessage) <> 0) or
+ (Pos('no connection to the server', sLCMessage) <> 0) then
eKind := ekServerGone
else
eKind := ekOther;