5

初期化時にデータ ソースを使用して単一のQueryRunnerをインスタンス化する Web サービスがあります。Web アプリケーションで使用される複数の異なるサーブレットからのすべてのサーブレット リクエストに対して、この 1 つのQueryRunnerオブジェクトをサーブレット コンテキスト属性として渡すことによって使用します。すなわち:

// in servlet context listener (on app initialization)
QueryRunner myQueryRunner = new QueryRunner(myDataSource);
myServletContext.setAttribute("queryRunner", myQueryRunner);

// in the servlets
QueryRunner myQueryRunner = (QueryRunner) myServletContext.getAttribute("queryRunner");
myQueryRunner.query(myStoredProcedure, handler, params)

それがボトルネックかどうかを把握しようとしています。代わりに、サーブレットQueryRunnerはすべてのリクエストで新しいインスタンスを作成する必要がありますか?

答えを探していると、このAsyncQueryRunnerも見つかりました。しかし、QueryRunnerAsyncQueryRunnerの API ドキュメントの説明にはまったく同じことが書かれているため、さらに混乱しました。

ここで例を調べたところ、すべてのリクエストでインスタンス化する必要があるようですが、それがサンプルコードであるという理由だけであるかどうかはわかりません.

つまり、DBUtils を使用する場合、次のことをQueryRunner行う必要があります。

  1. QueryRunnerリクエストごとに単一のインスタンスを使用しますか? (私が今やっていること)
  2. QueryRunnerすべてのサーブレット要求で新しいインスタンスを作成しますか?
  3. AsyncQueryRunnerリクエストごとに単一のインスタンスを使用しますか?
4

1 に答える 1

6

QueryRunner はステートレスであるためスレッド セーフなクラスであり、マルチスレッド環境で単一のインスタンスを問題なく使用できます。

すべてのメソッドは自己完結型であるため、メソッド アクセスを同期化する必要がないため、ボトルネックを排除することもできます。

私は問題なく本番環境で使用しますが、実装は「すべてのステートメントで新しい QueryRunner をインスタンス化する」というパターンに従います。これは、状態のない委任クラスであるため、重い初期化やヒープの消費がなく、シングルトンまたは他の共有インスタンスを使用しないためです。そのようなタイプのクラスを保存します。

AsyncQueryRunner もスレッド セーフですが、その目的と使用法はまったく異なります ( http://commons.apache.org/proper/commons-dbutils/examples.htmlを参照)。長時間実行ステートメントの非ブロッキング呼び出しを作成するために使用されます。ビジネス層を非同期にする必要がある場合に役立ちます。

結論は:

  • 複数のスレッドから単一の QueryRunner インスタンスを使用する (それぞれが 1 つのスレッドを要求しますか?) 反対の兆候はありませんが、利点もありませんが、このインスタンスを管理するためにどこかに少しのコードが必要です
  • スレッドごと、または委任するステートメントごとにでも、新しい QueryRunner インスタンスを使用します。これには、2 つの主な利点があります。シンプルでローカライズされた使用であり、必要がない場合はインスタンスがメモリ内にありません。
  • AsyncQueryRunner は、クエリ応答の面倒な管理を必要とするため、ビジネス コードで非同期動作が必要な場合にのみ使用してください。
于 2014-01-19T19:22:48.040 に答える