防止和报告数据库连接泄漏的一项建议:
首先找出每个连接的范围。
例如,对于许多 Web 应用程序,请求范围内需要连接。
定义好范围后,您需要做的就是在范围生命周期结束时以确定的方式关闭连接。
在 Web 应用程序中断言数据库连接始终关闭的一种方法是创建一个 servlet 过滤器,该过滤器将在请求进入时获取连接,并在发送响应时关闭连接。通过将连接放在 ThreadLocal 变量中,可以将连接从过滤器传递到其他对象。
范围的另一个示例是每个事务都需要连接时。您可能希望使用 Execute Around Method模式在范围开始之前获取连接,并在最后以确定性方式关闭它。
如果您实现了这些想法中的任何一个,您甚至可以在关闭连接之前记录哪些连接未关闭,以帮助识别泄漏。
祝你好运,我希望这会有所帮助,否则请告诉我。
更新:
我刚刚通过向数据库连接池实现 apache 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 配置