大きな結果セットで選択を行うJavaバッチがあります(Springコールバックハンドラーを使用して要素を処理します)。callbackhandlerは、行を処理するためにタスクを固定スレッドプールに配置します。私のプールサイズは16スレッドに固定されています。結果には約100kの要素が含まれています。すべてのdbアクセスコードはJdbcTemplateまたはHibernate/Springを介して処理され、手動の接続管理はありません。AtomikosとCommonsDBCPを接続プールとして使用してみました。
さて、このバッチを終了するには、接続プール内の最大17の接続で十分だと思います。1つは選択用で、16は接続プール内のいくつかの行を更新するスレッド用です。ただし、最大プールサイズを1桁大きく指定する必要があるため(正確な値を試していません)、最初にローカルWindowsマシンで動作する50を試しましたが、そうではないようです。 Unixテスト環境では十分です。そこで、それを機能させるために128を指定する必要があります(ここでも、50から128の間の値を試していませんでしたが、直接128になりました)。
これは正常ですか?私が見逃している接続プールの基本的なメカニズムはありますか?開いた接続で何が起こるかを確認する方法がわからないため、これをデバッグするのは難しいと思います。さまざまなlog4j設定を試しましたが、満足のいく結果が得られませんでした。
編集、追加情報:接続プールのサイズが小さすぎると思われる場合、バッチがハングしているようです。プロセスでjstatを実行すると、すべてのスレッドが新しい接続を待機していることがわかります。最初は、dbcp接続プールでmaxWaitプロパティを指定しなかったため、スレッドは新しい接続で無期限に待機し、バッチがハングし続けていることに気付きました。したがって、接続は解放されませんでした。ただし、これは+ -70k行を処理した後にのみ発生し、接続リークの最初の兆候をなんとかして却下しました。
edit2:タスクの更新部分をすでに書き直したことを忘れました。ConcurrentLinkedQueueで更新を確認し、1000個の要素で更新を空にします。だから私は実際には約100回の更新しか行いません。
edit3:Oracleを使用しており、並行utilsを使用しています。したがって、16の固定プールサイズで構成されたエグゼキューターがあります。このエグゼキューターでタスクを送信します。タスクで接続を手動で使用するのではなく、スレッドセーフで接続プールからの接続を要求するjdbctemplateを使用します。Spring/DBCPが接続/スレッドの問題を処理すると思います。