ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Tomcat连接池:几种不释放连接的方法

2019-10-12 01:05:14  阅读:405  来源: 互联网

标签:java jdbc tomcat connection-pooling


我正在使用tomcat连接池.但是我在跟踪异常
org.apache.tomcat.dbcp.dbcp.SQLNestedException:无法获得连接,池错误超时等待空闲对象

所以我在context.xml中放入以下行以查找泄漏:
removeAbandoned =“ true” logAbandoned =“ true” removeAbandonedTimeout =“ 3”

然后我开始获取以下异常org.apache.tomcat.dbcp.dbcp.AbandonedTrace $AbandonedObjectException:从未关闭通过以下代码创建的DBCP对象2015-01-17 22:12:18:
因此,我发现了导致这种泄漏的两种罪魁祸首方法.两种方法都有获得连接的通用方法,即调用unwrap获得对驱动程序特定连接的访问​​权限.

try (Connection conn = DataSourceConnectionPool.getConnection().unwrap(OracleConnection.class);
        OracleCallableStatement cstmt = (OracleCallableStatement) conn.prepareCall(MIGRATE_ACCOUNT)) {
        ...
        ....
)

需要注意的重要一点是,我正在使用JDK7中的try块,即自动资源管理,因此我不需要finally块.连接关闭由JDK自动处理.但是为什么这个展开的连接没有关闭.当我尝试执行以下操作时:

try (Connection poolConn = DataSourceConnectionPool.getConnection();
    Connection conn = poolConn.unwrap(OracleConnection.class);

我正在获取java.sql.SQLException:已经关闭.那么如何关闭此连接.我是否必须手动执行而不使用try块?不应该尝试阻止句柄来处理吗?

解决方法:

这是对连接池的不正确使用.绝对不要在未包装的连接上调用close().

使用池连接的正常流程是

>获取连接,池将获得物理连接,并将其包装在自己的包装器中返回
>您使用连接
>您可以在Connection上调用close().这实际上并没有关闭任何内容,池的包装程序拦截了close()调用,只是将(仍处于活动状态的)连接返回给池.

之所以可行,是因为该池具有包装器类,例如实现Connection的PoolableConnection. PoolableConnection委托底层连接进行实际工作,但它(除其他事项外)以不同的方式实现close().这将破坏当前的PoolableConnection包装器,并将底层的Connection返回到连接池.例如.

这样,您的程序逻辑可以从数据源获取连接,使用Connection,然后使用close(),就像正常的非池化Connection一样.

正是这种透明性使连接池易于使用.

现在,当您调用unwrap时,PooledConnection使您可以访问其内部的,真实的Connection委托.

您要做的就是在委托上调用close()!

这有两个效果:

>它不会在PooledConnection上调用close(),因此Connection不会返回到池中.
>它关闭了池下的底层连接.这不应该成为问题,因为池本身将处理掉线的连接.

因此,您需要非常小心.始终在从池中获得的Connection上调用close(),以将其返回到池中.永远不要在基础连接上调用close().

因此,您的代码应为:

try (final Connection poolConn = DataSourceConnectionPool.getConnection()) {
    final Connection conn = poolConn.unwrap(OracleConnection.class);
    //do stuff with conn
    //do not close conn!!
}
//poolConn is returned to the pool

标签:java,jdbc,tomcat,connection-pooling
来源: https://codeday.me/bug/20191011/1896581.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有