JavaでのJDBC接続の数
-
19-08-2019 - |
質問
約15のメソッドで構成されるJavaプログラムがあります。また、これらのメソッドは、プログラムの実行中に頻繁に呼び出されます。現時点では、すべてのメソッドで新しい接続を作成し、それらのステートメントを呼び出しています(データベースはネットワーク上の別のマシンにセットアップされています)。
私が知りたいのは、メインメソッドで1つの接続のみを作成し、それを接続オブジェクトを必要とするすべてのメソッドに引数として渡すと、プログラム内の接続オブジェクトの数が大幅に減少するためです。すべての方法で接続を頻繁に作成および終了する代わりに。
現在の設計ではリソースを非常に効率的に使用していないと思われ、このプログラムが将来大きくなる可能性があることを考えると、改善の余地がたくさんあります。
解決
はい、毎回新しい接続を作成するのではなく、接続の再利用を検討する必要があります。通常の手順は次のとおりです。
- データベースが合理的に処理できる同時接続数について推測します(たとえば、データベースマシンのCPUごとに2または3から開始し、これが少なすぎるか多すぎると判明するまで、これは依存する傾向があります)クエリがどのようにディスクにバインドされているかについて)
- この多数の接続のプールを作成します。基本的には、<!> quot;次の空き接続<!> quot;を要求できるクラスです。各メソッドの先頭で<!> quot; pass back <!> quot;各メソッドの最後にあるプールへ
- getFreeConnection()メソッドは、使用可能な場合は無料の接続を返す必要があります。そうでない場合は、(1)許可する接続の最大数まで新しい接続を作成するか、(2)最大接続既に作成されています。1つが空くのを待ちます
- 接続の管理にはSemaphoreクラスをお勧めします。私のWebサイトには、 Semaphoreを使用したリソースプールの管理に関する短い記事があります。あなたの目的に適応できると思う例
いくつかの実用的な考慮事項:
- 最適なパフォーマンスを得るには、 <!> quot; hog <!> quot;に注意する必要があります。実際に接続を使用してクエリを実行していない間。プールから一度接続を取得し、それをさまざまなメソッドに渡す場合、誤ってこれを実行していないことを確認する必要があります。
- 接続をプールに戻すことを忘れないでください! (試用/最終的にあなたの友達です...)
- 多くのシステムでは、接続を「永久に」開いたままにすることはできません:最大時間が経過すると、O / Sは接続を閉じます。したがって、「プールへの接続を返す」メソッドでは、長い間存在していた「リタイア」接続について考える必要があります(たとえば、このようなメトリックを格納するために使用できる実際のJDBC接続オブジェクトを囲むラッパーオブジェクト)
- 準備済みステートメントの使用を検討することもできます。
- 時間が経つにつれて、おそらく接続プールのサイズを微調整する必要があります
他のヒント
接続を渡すか、Jakarta Database Connection Poolingなどを使用することをお勧めします。 http://commons.apache.org/dbcp/
接続プールを使用する必要があります。
その方法で接続を要求し、終了したら解放してプールに戻すことができます
別のスレッドが新しい接続を必要とし、その接続が使用中の場合、新しい接続を作成できます。他のスレッドが接続を使用していない場合、同じスレッドを再利用できます。
この方法で、アプリをそのままの状態のままにして(接続をすべて渡さない)、リソースを適切に使用できます。
残念ながら、ファーストクラスのConnectionPoolは、スタンドアロンアプリケーション(アプリケーションサーバーのデフォルトです)での使用はそれほど簡単ではありません。おそらく、マイクロコンテナー(Spingなど)または優れたフレームワーク(Hibernateなど)を使用できます。
最初からコーディングするのはそれほど難しくありません。
:)
このGoogle検索使用方法の詳細を見つけるのに役立ちます。
スキムスルー
多くのJDBCドライバーが接続プーリングを行うため、この場合、追加のプーリングを行う利点はほとんどありません。 JDBCドライバーのドキュメントを確認することをお勧めします。
接続プールへの別のアプローチは次のとおりです
- 同期アクセスですべてのデータベースアクセスに1つの接続を用意します。これは並行性を許可しませんが、非常に簡単です。
- 接続をThreadLocal変数に保存します(initialValue()をオーバーライドします)。これは、スレッドの固定数が少ない場合に有効です。
それ以外の場合は、接続プールを使用することをお勧めします。
アプリケーションがシングルスレッドの場合、またはすべてのデータベース操作を単一のスレッドから実行する場合、単一の接続を使用しても問題ありません。他の理由で複数の接続が必要ないと仮定すると、これがはるかに簡単な実装になります。
ドライバーによっては、スレッド間で接続を共有することも可能です。これは、ドライバーがスレッドの安全性について嘘をつかないことを信頼している場合も同様です。詳細については、ドライバーのドキュメントを参照してください。
通常、以下のオブジェクト<!> quot; Connection <!> quot;複数のスレッドから安全に使用することはできないため、通常、スレッド間でResultSet、Statementオブジェクトなどを共有することはお勧めできません-最良のポリシーは、それらを作成した同じスレッドで使用することです。通常、これらのオブジェクトはあまり長く保持されないため、これは簡単です。