2017-05-19 10 views
0

私たちのコード(タイマーを介してスケジュールジョブとして実行される)では、データベース操作を実行するためにスレッドが並列に実行されています。ここでの問題は、各スレッドがHibernateファクトリ経由で接続を開始していることです。これらの接続は、すべてのデータベース操作の後に閉じられますが、接続プール内にstilが格納されます(INACTIVEとして)。すべての接続は、ジョブ/メインプロセスが終了した後にのみ解放されます。データベース操作後に接続プールからでも接続を解除する方法はありますか。タイマーの代わりにcronジョブを使うと、プロセスは自動的にkillされますが、ここでcronは必要ありません。 すでに生産リリースに近づいているので、これを解決するお手伝いをしてください。 注:QAが仕事に重い負荷をかけてテストされ、各負荷に対して新しい接続が引き出されたとき、これについて知りました。接続プールからの接続の解放

+0

はプールではなく接続リークのように聞こえます。 –

+0

同じと思われます。しかし、私たちはコードを読んで、すべての接続を閉じていることを確認しました。何が起こるかは、接続を閉じるときに、プールに戻すのではなくプールに戻って、メールスレッドが強制終了されたときにのみプールが解放されることです。実際にプロセスを終了せずにプールを解放することはできますか? –

答えて

1

スレッドプールで作成するスレッドの数を制限する必要があります。

dotConnect for Oracleは接続プーリングを使用します。 OracleConnection接続文字列にはPoolingパラメータがあります。 Pooling = true(デフォルト値)の場合、接続は閉じられた後で削除されず、代わりにプールに配置されます。同じ接続文字列を持つ新しい接続が開かれると、新しい接続の作成ではなく、空いている接続がある場合はプールから取得されます。これにより、パフォーマンスが大幅に向上します。 10〜15秒間接続された800個の接続を使用していて、わずかな接続文字列しかない場合は、800個の実際の接続がない可能性があります。クローズされた接続はプールに配置され、同じ接続文字列で新しい接続が開かれるとプールから取得されます。この場合、追加の接続は開きません。

接続文字列に 'Pooling = false'を追加することで、Poolingを無効にすることができます。このような場合、接続はメモリから削除され、セッションが解放されます。ただし、これによりパフォーマンスが低下する可能性があります。

ほとんどの場合、プーリングによってセッションが過度に作成されるべきではありません。プーリングを使用してアプリケーションをテストしてみてください。セッション番号が大きすぎる場合は、プーリングを無効にすることができます。詳細については

は、http://www.devart.com/dotconnect/oracle/docs/FAQ.html#q54

+0

私たちはそれが既存のレガシーデザインであるので、それをやりません、人々は今何かを変えたくありません。その他の提案はありますか?スレッドの中断やスレッドの強制終了は、プールからの接続を解放しますか?プール接続はいつ解放されますか? –

+0

スレッドを強制終了または停止することはできません。作成するスレッドの数を制限する必要があります。もう一つの選択肢は、すでに完了しているジョブが完了したときに接続を閉じることです。どのDBを使用していますか? db側で作成できる接続数を制限できる場合は文書をチェックしてください。 –

+0

Oracle 11gを使用しています。はい、私たちはスレッドプールのサイズと他のパラメータを介して同じを制限することができます。ここでの別の問題は、データベースコールが行われるたびにセッションファクトリが起動され、アプリケーション全体で汎用的に使用されるためのシングルトンとして作成されないことです。また、私が制限する場合、スレッドは他のスレッドが接続を解放するのを待たなければなりません。プール接続を解放する方法を知らなくても、デッドロックが発生します。プール接続を手動で解放するオプションはありますか? –

0

を参照してください私は、問題の根本的な原因を発見したとも解決策を発見しました。 根本的な原因は、最小値と最大値として設定された接続数とタイムアウトパラメータです。 最小値は5、最大値は20、タイムアウトは800秒です。しかし、仕事は毎分実行される予定でした。構成のため、接続は分以内に適切に解放されませんでした。 もう1つの問題は、私たちのコードがセッションファクトリをシングルトンとして使用していないことでしたが、スレッドごとに初期化していたことです。リソースは共有されていないため、各セッションファクトリはデフォルトで5つの接続を作成し、最大20まで拡張します。接続が解放される前にタイムアウトも高くなっていたため、次の一連のジョブが開始され、独自の新しい接続セットが作成されます。 最後にプールが満杯になり、Oracleが使用できなくなります。

セッションオブジェクトを共有し、タイムアウト値を小さく設定して接続がプールから解放されるように修正しました。