当社の製品の 1 つのアーキテクチャは、典型的な 3 層ソリューションです。
- C# クライアント
- WCF Web サービス
- SQL Server データベース
クライアントは、Web サービスからの情報を要求します。Web サービスはデータベースにアクセスして情報を取得し、それをクライアントに返します。
これが問題です。これらのクエリの中には非常に長い時間がかかるものもあり、どのクエリが遅くなるかを事前に知ることはできません。他のものよりも遅いことが多いものもありますが、十分なデータがあれば、最も単純なリクエストでも遅くなる可能性があります。大量のデータに対してクエリを使用したり、レポートを実行したりすることがあります。膨大な量のデータによってクエリが遅くなる前に、クエリを最適化できます。
データベースのクエリが SQL サーバーの最大クエリ タイムアウトに達した場合、データベース クエリは終了し、Web サービスはクライアントにエラーを返します。これは理解できます。これらのエラーを処理できます。
クライアントは、Web サービス呼び出しが完了するのを待っています。データベースの呼び出しに時間がかかる場合、クライアントは Web サービスへの呼び出しでタイムアウトになる可能性があります。クライアントはあきらめますが、データベース要求は処理を続けます。この時点で、クライアントはデータベースと同期していません。データベース呼び出しは、成功する場合と失敗する場合があります。エラーが発生した可能性があります。クライアントは決して知りません。場合によっては、前のリクエストの完了後に無効な状態になる可能性のある別のリクエストをユーザーが開始したくない場合があります。
他の人がこの問題をどのように処理したかを知りたいです。 Web サービスのタイムアウトがデータベース呼び出しに影響しないようにするために、どのような戦略を使用しましたか?
私が思いつく最良のアイデアは、実際のデータベース レイヤーをどこかに作成することです。Web サービス内で、メッセージ キューに接続します。すべてのクエリを別のプロセスにオフロードするのは過剰に思えます。(繰り返しになりますが、特定のリクエストが速いか遅いかは常にわかりません。)
HTTP リクエストを作成する行為を、データベース プロセスを開始して実行する行為から分離できれば素晴らしいことです。前の会社のカスタム サーバーでこれを行ったのを見たことがありますが、ストレート ソケット通信を使用していたため、Web サービスをカスタム アプリケーションに置き換えることは避けたいと考えています。
処理するデータの量を考えると、クエリの最適化がすべて終わっていることに注意してください。クエリの最適化、インデックスなどは、データ量が多い場合にのみ有効です。物事には長い時間がかかることがあります。