DBCP 返回关闭的连接

发布于 2024-12-03 08:58:26 字数 864 浏览 5 评论 0原文

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

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

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

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

将代码更新为捕获此类异常并在发生时请求新连接,但又失败了。我是否正确怀疑调用 DataSource#getConnection() 实际上并没有在每次调用时提供新连接?不就是重用已经关闭的现有连接吗?

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

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

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

“c1 == c2”是一个真实的陈述吗?或者已经分配了两个连接?如果是后者,像这样的代码是否代表“连接池泄漏”:

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

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.

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?

EDIT: 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(); 

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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

乖乖 2024-12-10 08:58:26

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

  1. 连接池将连接保持打开状态的时间过长。
  2. 数据库在太短的时间后关闭连接。

理论上,增加/减少两侧的超时以使其对齐应该可以解决问题。

在 DBCP 上,最好的办法是在返回之前通过 testOnBorrow=truevalidationQuery 设置(例如 SELECT 1)验证连接。您可以在 Tomcat JDBC 数据源文档< /a>.


根据您的更新更新

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

连接 c1, c2;
c1 = DatabaseManager.getConnection();
// c1.close() 未调用
c2 = DatabaseManager.getConnection(); 

“c1 == c2”是一个正确的陈述吗?或者已经分配了两个连接?

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

如果是后者,这样的代码是否代表“连接池泄漏”:

连接 c1;
c1 = DatabaseManager.getConnection();
// c1.close() 未调用
c1 = DatabaseManager.getConnection();

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

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

  1. The connection pool holds connections open for too long.
  2. The DB closes connections after a too short time.

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

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.


Update as per your update:

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(); 

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

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();

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".

寄离 2024-12-10 08:58:26

我也面临着同样的问题。然后我意识到我正在进行多个异步 ajax 调用,从而导致了问题。

我连续调用了这些调用并解决了问题。

I was also facing the same issues. then i realized that i was making multiple asynchronous ajax calls that was causing the issue.

I serialized the calls and it fixed the issue.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文