2

65 個のモジュールを持つデスクトップ アプリがあり、その約半分が SQLite データベースから読み書きされます。データベースが SQliteDatabaseError をスローする方法は3 つあります。

  1. SQL 論理エラーまたはデータベースの欠落 (時々予期せず発生)
  2. データベースがロックされている (SQLite Database Browser などの別のプログラムによって編集されている場合)
  3. ディスク I/O エラー (予期せず発生することもあります)

これらのエラーは頻繁に発生するわけではありませんが、発生するとアプリケーションが完全にロックされるため、そのままにしておくことはできません。

そのため、データベースへのすべてのアクセスを、独自のモジュール内の共通の「データベースアクセス関数」へのポインターになるように書き直し始めました。その関数は、これら 3 つのエラーを例外としてキャッチできるため、クラッシュせ、それに応じてユーザーに警告することもできます。たとえば、「データベースがロックされているというエラー」の場合は、これを通知し、データベースを使用しているプログラムを閉じてから再試行するようにユーザーに求めます。(他のエラーの場合は、ユーザーに後で再試行するように指示する可能性があります...まだわかりません)。これを行うためにすべてのデータベース アクセスを更新することは、ほとんどの場合、共通の機能へのリダイレクトをコピーして貼り付けるだけです。簡単な作業です。

問題は、このデータベース アクセス機能とその通知を提供するだけでは十分ではないということです。これは、65 個のモジュールのデータベース アクセスのすべてのポイントで、データベースがデータを正常に返すか完了することを前提としたアクセスに続くコードがあるためです。書き込み--そうでない場合、そのコードにはそのための条件が必要です。ただし、これらの条件文を作成するには、各アクセス ポイントを注意深く調べて、最適な処理方法を検討する必要があります。この方法でパッチを適用する必要がある数百回のデータベース アクセスには、これは面倒で困難です。

私はそれを喜んで行いますが、より効率的で賢い方法、または少なくともこの修正を効率的かつ適切に完了するのに役立つヒューリスティックがあるかどうかを問い合わせると思いました。

(このアプリケーションには特定の「アーキテクチャ」はないと述べておく必要があります...ほとんどの場合、「ラビオリ コード」と呼ばれるものであり、GUI とデータベースの呼び出しとロジックがすべて「一緒に機能する」単位でまとめられています。現時点では、プロジェクト全体のアーキテクチャを MVC などで書き直すつもりはありませんが、将来のプロジェクトでは検討したいと思います。)

4

1 に答える 1

1

あなたの直感は正しいです。各データベース アクセス ポイントを個別に確認せずに、アプリケーションに堅牢性を追加する方法はありません。

次のような要因に応じて、アプリケーションがエラーにどのように反応するかについて、まだ多くの重要な選択肢があります。

  • それは出席されていますか、それとも完全に無人である場合もありますか?
  • 遅延は問題ありませんか、それともデータベース エラーを速やかに報告することが重要ですか?
  • あなたが説明する 3 つのタイプの故障の相対頻度はどれくらいですか?

これで単一のラッパーができたので、それを使用して一般的な構成とエラー処理を行うことができます。特に:

  • 妥当な接続タイムアウトを設定する
  • 妥当なビジー タイムアウトを設定する
  • クライアント側でコマンドのタイムアウトを強制する
  • エラーが発生した場合、特にSQLITE_BUSY(再試行の間に大きな遅延を挿入し、数回の再試行後に失敗する)で自動的に再試行します。
  • 例外を使用して、アプリケーション レベルのハンドラーの数を減らします。データベース エラーが発生した場合、アプリケーション全体を再起動できる場合があります。ただし、どの状態でアプリケーションを中止するか確信がある場合にのみ行ってください。トランザクションを一貫して使用することで、再起動メソッドが一貫性​​のないデータを残さないようにすることができます。
  • ロックエラーを検出したときに人間に助けを求める

...しかし、弾丸をかじってアプリケーションにエラーを出力し、特定の呼び出し元がそれに対して何をする可能性があるかを確認する必要がある瞬間が来ます。

于 2012-06-26T21:04:59.273 に答える