java tomcat连接池_Tomcat连接池:几种不释放连接的方法

我正在使用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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值