【问题标题】:TFDConnection.OnRecover is never fired when PostgreSQL stopsPostgreSQL 停止时不会触发 TFDConnection.OnRecover
【发布时间】:2019-03-11 13:56:04
【问题描述】:

我使用了 Recovering Connection (FireDAC) 中所述的 Firedac 连接恢复功能,并且在 Delphi XE5 上一切正常。

我安装了 Delphi 社区版本 10.2、10.3 和 10.3.1 进行迁移测试,发现数据库重新连接功能无法正常工作。

使用场景:

  • Windows 10 PRO X64 1803
  • 德尔福 10.2 / 10.3 / 10.3.1
  • PostgreSQL 9.5.16 x64

重现问题的步骤:

1 - 创建一个新的 VCL 应用程序;

2 - 在 Form1 上,删除组件 TFDConnection、TFDPhysPgDriverLink、TFDGUIxWaitCursor、TFDQuery 和 TButton;

3 - 使用 PostgreSQL 的连接参数和 TFDPhysPgDriverLink 的 vendorlib libpq.dll 配置 TFDConnection;

4 - 按照Recovering Connection (FireDAC) 中的说明配置 TFDConnection;

5 - 在 TButton OnClick 事件中放置以下内容:

qry1.Close;
qry1.Open ('select 1');

6 - 在 TFDConnection 的 OnRecover 事件中放入下面的代码,如 Recovering Connection (FireDAC) 所述:

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

【问题讨论】:

  • 您是否在 qry1.Close 之前先尝试过TFDCustomConnection.Ping,看看是否也失败了?
  • @mjn,感谢您的评论。我试过但没有任何改变。问题依然存在。
  • 您是否不小心将EFDDBEngineException 添加到抑制的异常列表中? (参见 IDE 选项中的“语言异常”)
  • @mjn,再次感谢,但在 Delphi 的配置中并没有忽略 EFDDBEngineException。例如,在步骤 9 中,如果我禁用网络适配器,将其禁用,然后执行步骤 10,将触发 TFDConnection.OnRecover 事件。服务重启或网络不稳定时会出现问题。但在 Delphi XE5 中一切正常。
  • 你最好添加这个补丁作为答案。

标签: delphi


【解决方案1】:

根据 RSP-23958,我向 Embarcadero 质量中心报告了这个问题,并且该错误已得到解决。有人叫 Dmitry 回答说这个问题将在 Delphi 10.3 的更新 2 中得到解决。

在 RSP-23958 中,附带了一个解决问题的修复补丁,如果你有 Dephi 和 Firedac 源代码,而 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;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-02
    • 2013-07-29
    • 1970-01-01
    • 2015-11-26
    • 2021-07-14
    • 2015-01-22
    相关资源
    最近更新 更多