このADOエラーメッセージをグーグルで検索すると、ASP.NET開発で一般的に発生することがわかりますが、Delphiアプリケーションでいつ発生するかについてはあまり言及されていません。一時的なネットワークの問題が発生しているお客様のサイトがいくつかありますが、これは症状のあるエラーメッセージです。オフィステストで簡単に複製できます。delphiTADOConnectionオブジェクトがそのサーバーインスタンス上のデータベースに接続されている間にMSSQLServerサービスをシャットダウンするだけで、次の例外が発生します。
[DBNETLIB][ConnectionWrite (send()).]General network error. Check your network documentation.
はい、この例外をキャッチすると、このエラーが発生したことがわかります(またはわかりますか?)。これが、データベースアクションの周りのブロックを除いて10,000回を超える試行を伴う800 KLOC +アプリケーションであることを除いて、いずれもこのエラーで失敗する可能性があります。
TADOConnection
いくつかのエラーイベントがありますが、この場合はいずれも発生しません。ただし、これが発生するとADO接続自体に障害が発生します。SQLデータベースを再起動しても、TADOConnection.Connectedはtrueのままですが、それはあなたに嘘をついています。本当に故障状態です。
それで、私の質問は:
この障害状態を検出し、それから回復することはできますか?ブロックを除いて10,000回の個別の試行を行い、グローバルな「再接続ADOグローバル変数」を設定するよりも少ない作業で済みますか?
TADOConnection.ConnectionObject(基になる生のOLEDB COM ADOオブジェクト)にアクセスして、新しいクエリを開始するときにこの障害状態が存在することを検出する方法があることを期待しています。これにより、ADOConnectionをリセットして、次に実行するときに続行できます。クエリ。私たちのコードは、10行のデモアプリケーションでこれを行う方法よりもはるかに簡単に「障害後」にこれを検出できるように編成されているためです。
この他のSOの質問は、なぜそれが起こるのかを尋ねます、それは私が求めているものではありません、私に「予防」の答えを与えないでください、私はすでにそれらについて知っています、私は回復と失速したADOの検出を探しています-例外をキャッチする以外の接続手法。実際、これは例外がうまくいかなかった良い例です。ADOは、この障害モードのschrodingers-catオブジェクトです。
私はMSナレッジベースの記事とインターネット上に浮かんでいるさまざまなソリューションを知っています。エラー状態(私たちの状況では一時的なものであることが多い)が解消されたら、顧客データを失うことなく回復することについて質問しています。つまり、アプリをフリーズし、お客様に例外を表示し、お客様が[再試行]または[続行]をクリックすると、修復して続行を試みます。既存のコードは100万回の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か所にコピーして貼り付ける必要があることです。