首页 / JAVA / java – 连接池泄漏原因
java – 连接池泄漏原因
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 连接池泄漏原因,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3353字,纯文字阅读大概需要5分钟。
内容图文
![java – 连接池泄漏原因](/upload/InfoBanner/zyjiaocheng/825/5ca9d566fa3c49a088e156c9967b2475.jpg)
我一直在体验(我认为)连接池的问题.
具体来说,我的日志显示消息:
org.apache.tomcat.dbcp.pool2.impl.DefaultPooledObject$AbandonedObjectCreatedException: Pooled object created [time] by the following code has not been returned to the pool
我已经检查了日志显示的堆栈跟踪中列出的方法,但找不到罪魁祸首(我总是在每个方法结束时关闭ResultSet,PreparedStatement和Connection).
我有一个执行两个查询的方法,也许我没有正确执行它.
它的布局如下:
ConnectionPool pool = ConnectionPool.getInstance();
Connection connection = pool.getConnection();
PreparedStatement ps = null;
PreparedStatement rowsPs = null;
ResultSet rs = null;
ResultSet rowsRs = null;
String query = "SELECT SQL_CALC_FOUND_ROWS ...";
String totalRowsQuery = "SELECT FOUND_ROWS() AS RowCount";
try {
ps = connection.prepareStatement(query);
[set ps params]
rs = ps.executeQuery();
[process rs]
rowsPs = connection.prepareStatement(totalRowsQuery);
rowsRs = rowsPs.executeQuery();
[process rowsRs]
} catch (SQLException e) {
[handle e]
} finally {
DBUtil.closeResultSet(rs);
[close rowsRs]
[close ps]
[close rowsPs]
[close connection]
}
其中DBUtils方法的示例是:
public static void closeResultSet(ResultSet rs)
{
try
{
if (rs != null)
rs.close();
}
catch (SQLException sqle)
{
sqle.printStackTrace();
}
}
这种方法的总体布局是否正常?我应该以不同方式处理连接吗?或者是导致错误记录的其他方法?
谢谢.
附加信息
我也得到一个SQLException:
java.sql.SQLException: Connection com.mysql.jdbc.JDBC4Connection@[some number] is closed
在该行:rowsPs = connection.prepareStatement(totalRowsQuery);
意思是在之前的某个地方,连接已关闭.
我没有在任何地方明确关闭连接.
是否有可能某个其他数据访问方法在某种程度上关闭此方法中的连接? (pool.getConnection()调用dataSource.getConnection())
更新:
我已尝试按建议使用try-with-resources,但问题仍然存在.
上面第一个代码段中引用的ConnectionPool类:
public class ConnectionPool
{
private static ConnectionPool pool = null;
private static DataSource dataSource = null;
public synchronized static ConnectionPool getInstance()
{
if ( pool == null ) {
pool = new ConnectionPool();
}
return pool;
}
private ConnectionPool()
{
try {
InitialContext ic = new InitialContext();
dataSource = (DataSource)
ic.lookup([jdbc/dbName]);
}
catch (Exception e) {
e.printStackTrace();
}
}
public Connection getConnection()
{
try {
return dataSource.getConnection();
}
catch (SQLException sqle) {
sqle.printStackTrace();
return null;
}
}
public void freeConnection(Connection c)
{
try {
c.close();
}
catch (SQLException sqle) {
sqle.printStackTrace();
}
}
}
更多来源:
我的池资源元素:
<Resource auth="Container" driverClassName="com.mysql.jdbc.Driver"
logAbandoned="true" maxActive="100" maxIdle="30" maxWait="10000"
removeAbandonedOnBorrow="true"
removeAbandonedTimeout="60" type="javax.sql.DataSource"
testWhileIdle="true" testOnBorrow="true"
validationQuery="SELECT 1 AS dbcp_connection_test"/>
更新:
我打开了慢查询日志,但是,尽管再次抛出异常,慢查询日志不会记录任何内容(查询时间不超过10秒).
所以它似乎并非查询花费的时间超过60秒.
仍然不确定是什么导致了这一点.
解决方法:
作为使用池化JDBC连接时的一般经验法则:
>不要在每个连接上一次打开多个ResultSet.在打开第二个之前关闭第一个ResultSet及其关联的Statement.
>始终按照与创建它们完全相反的顺序关闭资源:create(s1) – > execute(r1) – > close(r1) – > close(s1) – > create(s2) – >执行(R 2) – >靠近(R 2) – >关闭(S2)
>确保长时间运行的查询处理未超过池允许的最大连接生存期.
>即使您没有超过最大连接寿命,由于网络链路中断很少,也可能会丢失连接.
内容总结
以上是互联网集市为您收集整理的java – 连接池泄漏原因全部内容,希望文章能够帮你解决java – 连接池泄漏原因所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。