データベース接続リークを防止および報告するための 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 構成