2011-03-10 6 views
1

開発中のデータベース接続プール "リーク"を追跡しようとしていますが、ユニットテストの設定の結果であるかどうかは疑問です。何かGlassfishプールからデータベース接続を取得し、終了時にそれらを閉じない。最終的にプールの最大接続が使い尽くされ、アプリケーションは新しいdb接続を取得できません。接続プール "リーク"が開発中です。それはJUnitテストの設定によるものでしょうか?

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

私たちは何を探すべきでしょうか?

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

+0

ていますか?アプリケーションが自動テストなしで使用されているときに接続リークが発生しますか? –

+0

テストとアプリケーションの両方がdb接続を使用しています。どちらが漏れの原因であるのかわからない。単体テストは、私たちが手動で行うことよりもはるかにシステムにストレスを与えます。単体テストの実行時に問題が発生します。 – Shane

+0

オープンコードとクローズコード以外のテストですべてをコメントアウトしてみてください。少なくとも、あなたはその部分が適切に動作していることを知り、アプリケーションが問題になっていることを指摘するかもしれません。 – Preston

答えて

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 configuration

1

接続を使用すると、実用的にそれを閉じると、接続がプールに戻され

  1. プールに戻されます(最終的にブロック!)
  2. フルガベージコレクションが
  3. するとjavaプロセスを発生します(サーバーの停止、ユニットサイクルの終了)

単なる単体テストの実行によるプールの問題はほとんどありません。

0

私はそれが(JUnitのバージョンに応じて、適切な方法signaturまたは注釈)適切なティアダウンされた場合にティアダウンを逃します見たことがない

しかし:例外が内部でスローされますときには、ティアダウンの部分をスキップするかもしれません取り壊す。

あなたのTestSuiteを実行し、接続プールを見て理論をテストしたいと思います。かなり簡単に聞こえます。データベース接続リークを防ぐと報告する

関連する問題