1

開発中のデータベース接続プールの「リーク」を追跡しようとしていますが、それが単体テストの設定方法に起因するものかどうか疑問に思っています。何かが Glassfish プールからデータベース接続を取得していて、完了してもそれらを閉じていません。最終的に、プールの最大接続数が使い果たされ、アプリケーションは新しいデータベース接続を取得できなくなります。

JUnit テストでは、setUp() メソッドでプールから接続を取得し、tearDown() メソッドでその接続を閉じます。teaDown() メソッドが常に実行されると確信できますか? 未処理の例外が発生した場合、tearDown() メソッドをバイパスできますか?

何を探すべきかについて他に何か考えはありますか?

Jakarta Cactus を使用して、Glassfish アプリケーション サーバーでこれらの単体テストを実行していることに注意してください。

4

3 に答える 3

1

接続は次の場合にプールに返されます

  1. 実用的にプールを閉じると、接続がプールに戻されます(最後にブロックします!)
  2. 完全なガベージコレクションが発生します
  3. Javaプロセスが強制終了されたとき(サーバーの停止、ユニットサイクルの終了)

つまり、単体テストの実行によってプーリングの問題が発生する可能性はほとんどありません。

于 2011-03-10T14:50:08.353 に答える
1

データベース接続リークを防止および報告するための 1 つの提案:

まず、各接続の範囲を確認します。

たとえば、多くの Web アプリケーションでは、リクエストのスコープ内で接続が必要です。

スコープを定義したら、あとはスコープのライフサイクルの最後に決定論的な方法で接続を閉じるだけです。

Web アプリケーションでデータベース接続が常に閉じていることをアサートする 1 つの方法は、要求が着信したときに接続を取得し、応答が送信されたときに接続を閉じるサーブレット フィルターを作成することです。接続は、ThreadLocal 変数に入れることで、フィルターから他のオブジェクトに渡すことができます。

スコープの別の例は、トランザクションごとに接続が必要な場合です。Execute Around Methodパターンを使用して 、スコープが開始する前に接続を取得し、最後に確定的な方法で接続を閉じることができます。

これらのアイデアのいずれかを実装すると、リークを特定するのに役立つように、閉じる前に閉じられなかった接続をログに記録することさえできます。

頑張ってください。これがお役に立てば幸いです。それ以外の場合はお知らせください。

アップデート:

データベース接続プール実装の apache DBCP にデバッグ パラメータを追加することで、レガシー コードのデータベース接続リークを解決しました。運用環境で DBCP を使用したくない場合でも、閉じられていない接続を借用した正確な回線コードを検出するためだけに、テストで DBCP を設定できます。

私の環境では、次のように JNDI データソース構成で tomcat を使用しました。

  <Resource auth="Container"
       name="jdbc/APP_NAME"
       username="user"
       password="password"
       url="jdbc:oracle:thin:@server.domain:1521:development"    
       type="javax.sql.DataSource"
       driverClassName="oracle.jdbc.driver.OracleDriver"

       maxIdle="10"
       maxWait="5000"
       maxActive="10"
       validationQuery="select 1 from dual"
       validationInterval="30000"
       testOnBorrow="true"
       testOnReturn="false"
       testWhileIdle="true"
       timeBetweenEvictionRunsMillis="5000"
       numTestsPerEvictionRun="3"
       minEvictableIdleTimeMillis="30000"


 <!-- These 3 settings saved me hours of headache -->

 logAbandoned="true" <!-- Will report the stacktrace of the faulty code --> 

 removeAbandoned="true" <!-- Will remedy the connection starvation while leaky code is not fixed-->

 removeAbandonedTimeout="60"<!-- Interval for fixing connection starvation while leaky code is not fixed-->

 />

参照: Apache DBCP 構成

于 2011-03-11T15:49:34.423 に答える
0

それが適切なtearDown(JUnitのバージョンに応じた適切なメソッド署名またはアノテーション)である場合、tearDownが見落とされるのを見たことがありません。

ただし、tearDown内で例外がスローされた場合は、tearDownの一部をスキップできます。

TestSuiteを実行し、接続プールを監視して、理論をテストします。私にはかなり簡単に聞こえます。

于 2011-03-10T14:50:54.700 に答える