mysql - DB连接池过期了怎么办?

标签 mysql jdbc playframework connection-pooling c3p0

连接池过期后,当我尝试并行打开的连接数超过池中允许的最大连接数时,我在尝试从池中获取连接时开始出现超时异常。

这是预料之中的,但是,池似乎保持在这种状态,从那一刻起我所做的所有其他事情都会得到相同的超时异常。就好像池中的每个连接都处于忙碌状态,并且无法重用。我希望随着时间的推移,连接会被释放,然后其他连接也会被允许,但这并没有发生。

我使用 Play 1.2.5 和 mysql 的 jdbc 驱动程序,从日志中我认为池是 C3P0。

我没有明确关闭连接,因为我相信使用池时这样做是正确的,但我不是 100% 确定。

我不知道这是否可能是我正在使用的框架/库之一的连接泄漏,或者我是否做错了什么或没有做我应该做的事情。

当我捕获一个超时异常时,正确的做法是什么?

最佳答案

使用连接池时,您必须显式关闭连接。连接池具有数据库物理连接的集合。当您从池中请求连接时,它会将该物理连接标记为正在使用,并为您提供该连接的逻辑句柄。该逻辑句柄本质上是一个包装器或代理,它将大多数方法调用(直接或经过一些修改)转发到物理连接。

当您在此逻辑句柄上调用 close() 时,连接池会收到一个信号,表明物理连接再次可用(即:可以返回到pool),逻辑句柄从此将表现为关闭的连接,但实际的物理连接仍然打开。如果您不调用 close(),连接池永远不会收到此信号,因此物理连接将保持使用中状态并且无法重复使用.

一些高级池配置允许池检测这种情况(例如使用超时,或者可能使用终结器等)并回收连接,但您不应该依赖于此。

TL;DR: 当您使用完连接后,始终对连接调用 close(),无论它来自连接池还是非池DataSourceDriverManager

关于mysql - DB连接池过期了怎么办?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14383735/

相关文章:

java - 将 mysql 配置移动到 JNDI

java - ebean 映射到 BYTEA 是什么数据类型?

php - 从两个表中选择不匹配的记录

php - MySql 在每次插入后插入最后一个 id

hibernate - 如何在docker环境中使用Mysql启动Aerogear统一推送服务器

java - spring jdbcTemplate如何捕获异常?

scala - play 2.4 控制台无法按文档工作

javascript - 如何使用 java 脚本 window.location 将参数传递给 play 框架中的 java 方法?

php - 查找两个用户之间的公共(public)列,如果没有则查找 null/0

mysql 中的 c++ 函数 make_scrambled_pa​​ssword 到 mariadb