gpt4 book ai didi

sql-server - 当 DBNETLIB ConnectionWrite 一般网络错误导致 ADO 连接在 Delphi 应用程序中脱机时自动恢复?

转载 作者:行者123 更新时间:2023-12-03 14:47:08 27 4
gpt4 key购买 nike

谷歌搜索此 ADO 错误消息表明它在 ASP.NET 开发中很常见,但我没有发现太多提及它何时发生在 Delphi 应用程序中。我们的一些客户站点遇到暂时性网络问题,这是有症状的错误消息。我们可以在办公室测试中轻松复制它;当您的 delphi TADOConnection 对象连接到该服务器实例上的数据库时,只需关闭 MS SQL Server 服务,您就会得到以下异常:

   [DBNETLIB][ConnectionWrite (send()).]General network error. Check your network documentation.

是的,捕获此异常,并且您知道(或者您知道吗?)发生了此错误。只不过这是一个 800 KLOC+ 应用程序,在数据库操作周围有超过 10,000 个 try- except block ,其中任何一个都可能因此错误而失败。

TADOConnection 有一些错误事件,在这种情况下都不会触发。然而,一旦出现这种情况,ADO Connection 本身就会出现故障,即使您重新启动 SQL 数据库,TADOConnection.Connected 仍然为 true,但它在欺骗您。确实处于故障状态。

那么,我的问题是:

您能否以比进入 10,000 个单独的 try- except block 并设置一些全局“重新连接 ADO 全局变量”更少的工作量来检测此错误状态并从中恢复?

我希望有一种方法可以进入 TADOConnection.ConnectionObject (底层原始 OLEDB COM ADO 对象)并在我们开始新查询时检测到此故障条件是否存在,以便我们可以重置 ADOConnection 并继续下一个我们运行查询的时间。由于我们的代码的组织方式使我们能够更容易地检测到“故障后”,而不是像我在 10 行演示应用程序中那样进行检测。

This other SO question询问为什么会发生这种情况,这不是我要问的,请不要给我“预防”答案,我已经知道它们了,我正在寻找恢复和检测-除捕获异常之外的停滞 ADO 连接技术。事实上,这是异常出错的一个很好的例子;在这种故障模式下,ADO 是一个薛定谔猫对象。

我知道 MS 知识库文章以及互联网上流传的各种解决方案。我问的是,一旦错误条件(在我们的情况下通常是暂时的)清除,就可以在不丢失客户数据的情况下进行恢复。这意味着我们卡住我们的应用程序,向客户显示异常,当客户单击“重试”或“继续”时,我们尝试修复并继续。请注意,我们现有的代码执行了一百万个 try- except-log-and- continue 代码,这将妨碍我们,所以我希望有人回答未处理异常的应用程序处理程序是最好的方法,但遗憾的是我们不能使用它。不过,我真的希望能够检测到卡住/故障/失效的 ADO 连接对象。

这是我所拥有的:

try
if fQueryEnable and ADOConnection1.Connected then begin
qQueryTest1.Active := false;
qQueryTest1.Active := true;
Inc(FQryCounter);
Label2.Caption := IntToStr(qQueryTest1.RecordCount)+' records';

end;
except
on E:Exception do begin
fQueryEnable := false;
Memo1.Lines.Add(E.ClassName+' '+E.Message);
if E is EOleException and Pos('DBNETLIB',E.Message)>0 then begin
ADOConnectionFaulted := boolean; { Global variable. }
end;
raise;
end;
end;

上述解决方案的问题是我需要在应用程序中复制并粘贴大约 10,000 个位置。

最佳答案

好吧,没有人回答这个问题,我认为一些后续行动会有所帮助。

这是我学到的:

  • 没有可靠的情况可以在测试环境中重现此一般网络错误。也就是说,我们正在处理不可重现的结果,这就是许多开发人员跳入邪恶黑客试图“修补”他们损坏的系统的地方。

  • 当 SQL 库给出“一般网络错误”时,修复根本错误始终比在代码中修复要好。没有任何修复被证明是可能的,因为通常这意味着“网络非常不可靠,以至于 TCP 本身已经放弃传递我的数据”,这种情况发生在以下情况:

    • 您的网络电缆损坏。

    • 网络上有重复的 IP 地址。

    • 您有相互竞争的 DHCP 服务器,每个服务器处理不同的默认网关。

    • 您的本地以太网网段之间的连接性较差。

    • 您的以太网交换机或集线器出现故障。

    • 您被故障的防火墙间歇性地阻止。

    • 您的客户可能已更改其网络上的某些内容,现在可能无法使用您的软件。 (最后一个实际上发生的次数比你想象的要多)

    • 有人可能使用 cliconfg 或特定于单个工作站注册表设置的其他客户端配置元素配置了 SQL 别名,并且此本地配置可能会导致难以处理的不良行为进行诊断,并且可能仅限于大型网络上的一个或多个工作站。

在 TCP 或 SQL 级别都无法检测和报告以上内容。当 SQL 最终放弃时,它给出了“一般网络错误”,我的软件再多的哄骗也无法让它放弃,即使这样做了,我也会做一个“尝试/异常(exception)”/忽略”反模式。这个错误非常严重,我们应该将其一直向上提交给用户,将其记录到磁盘的错误日志中,放弃(退出程序),并告诉用户网络连接已关闭。

关于sql-server - 当 DBNETLIB ConnectionWrite 一般网络错误导致 ADO 连接在 Delphi 应用程序中脱机时自动恢复?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10755560/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com