谷歌搜索此 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 块,其中任何一个都可能因此错误而失败。
TADOConnection
有一些错误事件,在这种情况下都不会触发。但是,一旦发生这种情况,ADO 连接本身就会出现故障,即使您重新启动 SQL 数据库,TADOConnection.Connected 仍然是正确的,但它是在骗您。它确实处于故障状态。
那么,我的问题是:
你能以任何比进入 10,000 个单独的 try-except 块并设置一些全局“重新连接 ADO 全局变量”更简单的方式检测到这种错误状态并从中恢复吗?
我希望有一种方法可以进入 TADOConnection.ConnectionObject (底层原始 OLEDB COM ADO 对象)并在我们开始新查询时检测到此故障情况,以便我们可以重置 ADOConnection 并在下次运行时继续一个问题。由于我们的代码的组织方式允许我们在“失败后”检测到这一点,而不是像我在 10 行演示应用程序中那样做。
This other SO question询问为什么会发生,这不是我要问的,请不要给我“预防”答案,我已经知道了,我正在寻找恢复和检测停滞的ADO - 连接技术,而不是捕获异常。事实上,这是异常出错的一个很好的例子;在这种故障模式下,ADO 是一个 schrodingers-cat 对象。
我知道 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 个位置。