DBCP返回已关闭的连接 [英] DBCP returns closed connections

查看:190
本文介绍了DBCP返回已关闭的连接的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们看到来自 org.apache.commons.dbcp.BasicDataSource 的数据库连接因套接字写错误而死的情况:

We are seeing situations where our database connection from org.apache.commons.dbcp.BasicDataSource is dying with socket write errors:

com.microsoft.sqlserver.jdbc.SQLServerException: Connection reset by peer: socket write error

所有后续写入连接的尝试都失败了,当然:

All subsequent attempts to write to the connection fail, of course:

com.microsoft.sqlserver.jdbc.SQLServerException: The connection is closed.

更新代码以捕获此类异常并在发生新请求时请求新连接后再次失败。我是否正确怀疑调用 DataSource#getConnection()实际上每次调用时都没有提供新连接?是不是只是重用现有的连接,这是关闭的?

After updating the code to catch such exceptions and request a new connection when it occurs, it failed again. Am I correct in suspecting that calling DataSource#getConnection() is not actually giving a new connection each time it is called? Isn't it just reusing the existing connection, which is closed?

如果我是正确的,什么是丢弃旧连接并请求新连接的正确方法?

If I am correct, what is the right way to throw away the old connection and request a new one?

编辑:这是我想知道的更为简洁的版本:

Here's a more succint version of what I'd like to know:

Connection c1, c2;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c2 = DatabaseManager.getConnection(); 

c1 == c2是真的陈述吗?或者分配了两个连接?如果是后者,那么像这样的代码表示连接池泄漏:

Is "c1 == c2" a true statement? Or have two connections been allocated? And if it's the latter, would code like this represent a "connection pool leak":

Connection c1;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c1 = DatabaseManager.getConnection();


推荐答案

数据库已关闭池化连接。这可能意味着两件事:

The pooled connection has been closed by the DB. That can mean 2 things:


  1. 连接池保持连接打开时间过长。

  2. 数据库在太短的时间后关闭连接。

理论上,增加/减少任何一方的超时以对齐它应解决问题。

In theory, increasing/decreasing the timeout on either sides to align it should fix the problem.

在DBCP上,最好的办法是在返回之前验证连接 testOnBorrow = true validationQuery 设置,例如 SELECT 1 。您可以在 Tomcat JDBC数据源文档<中找到配置选项/ a>。

On DBCP, your best bet is to validate connections before returning by a testOnBorrow=true and a validationQuery setting, e.g. SELECT 1. You can find configuration options in the Tomcat JDBC data sources documentation.

更新根据您的更新:


这是我想知道的更多简洁版本:

Here's a more succint version of what I'd like to know:

Connection c1, c2;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c2 = DatabaseManager.getConnection(); 

c1 == c2是真的陈述吗?或者分配了两个连接?

Is "c1 == c2" a true statement? Or have two connections been allocated?

这是两个截然不同的连接。只有当您调用 c1.close()时, c2 才有可能返回相同的连接。

It are two distinct connections. Only if you call c1.close() then there's a reasonable chance that c2 returns the same connection.


如果是后者,那么这样的代码就代表了连接池泄漏:

And if it's the latter, would code like this represent a "connection pool leak":

Connection c1;
c1 = DatabaseManager.getConnection();
// c1.close() not called
c1 = DatabaseManager.getConnection();


是的,肯定会泄漏第一个连接,因为它从来没有回到了游泳池。您应该始终 try-finally 块中以尽可能短的范围关闭所有数据库资源。然而,有点像样的连接池可以配置以获得废弃的连接,但这绝对不能用作解决方法。

Yes, definitely it will leak the first connection as it's never been returned to the pool. You should always close all DB resources in the shortest possible scope in a try-finally block. A bit decent connection pool is however configureable to reap abandoned connections, but this should definitely not be used as "workaround".

这篇关于DBCP返回已关闭的连接的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆