Hibernate c3p0 连接池不会超时空闲连接

Posted

技术标签:

【中文标题】Hibernate c3p0 连接池不会超时空闲连接【英文标题】:Hibernate c3p0 connection pool not timing out idle connections 【发布时间】:2010-11-25 09:28:05 【问题描述】:

我们有一个 java 服务器连接到 mysql 5 数据库,使用 Hibernate 作为我们的持久层,它使用 c3p0 进行数据库连接池。

我已尝试遵循 c3p0 和 hibernate 文档:

Hibernate - HowTo Configure c3p0 connection pool C3P0 Hibernate properties C3P0.properties configuration

我们在生产服务器上收到一个错误,指出:

... 原因: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: 连接后不允许操作 closed.Connection 是隐式的 由于基础而关闭 异常/错误:

开始嵌套异常

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException

MESSAGE: 最后一个包成功 从服务器收到的是45000 几秒钟前。发送的最后一个数据包 成功到服务器是45000 秒前,这比 服务器配置的值 '等待超时'。你应该考虑 过期和/或测试 在您使用之前的连接有效性 应用,增加服务器 客户端超时的配置值, 或使用连接器/J 连接 属性'autoReconnect = true'以避免 这个问题。

堆栈跟踪:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: 最后一个数据包成功接收 从服务器是45000秒 ago.最后一个包发送成功 到服务器是 45000 秒前, 比服务器长 'wait_timeout' 的配置值。 您应该考虑到期 和/或测试连接有效性 在您的应用程序中使用之前, 增加配置的服务器 客户端超时值,或使用 Connector/J 连接属性 'autoReconnect=true' 来避免这种情况 问题。

我们的 c3p0 连接池属性设置如下:

hibernate.c3p0.max_size=10
hibernate.c3p0.min_size=1
hibernate.c3p0.timeout=5000
hibernate.c3p0.idle_test_period=300
hibernate.c3p0.max_statements=100
hibernate.c3p0.acquire_increment=2

default MySQL wait_timetout 设置为 28800 秒(8 小时),报错是说已经超过 45000 秒(约 12.5 小时)。虽然 c3p0 配置声明它将“超时”5000 秒后未使用的空闲连接,并且它会每 300 秒检查一次,因此空闲连接的生存时间永远不会超过 5299 秒,对吧?

我已经通过设置我的开发人员 MySQL(Windows 上的 my.ini,Unix 上的 my.cnf)wait_timeout=60 并将 c3p0 空闲超时值降低到 60 秒以下进行了本地测试,它会正确超时空闲连接并创建新的那些。我还检查以确保我们没有泄漏数据库连接并保持连接,而且看起来我们不是。

这是我用来在开发人员环境中测试以确保 c3p0 正确处理连接的 c3p0.properties 文件。

hibernate.properties(使用 MySQL wait_timeout=60 进行测试)

hibernate.c3p0.max_size=10
hibernate.c3p0.min_size=1
hibernate.c3p0.timeout=20
hibernate.c3p0.max_statements=100
hibernate.c3p0.idle_test_period=5
hibernate.c3p0.acquire_increment=2

c3p0.properties

com.mchange.v2.log.FallbackMLog.DEFAULT_CUTOFF_LEVEL=ALL
com.mchange.v2.log.MLog=com.mchange.v2.log.FallbackMLog
c3p0.debugUnreturnedConnectionStackTraces=true
c3p0.unreturnedConnectionTimeout=10

【问题讨论】:

查看我的答案并检查并检查位于 hibernate.org 上的兼容性矩阵(即使我错过了该矩阵中的 c3p0) 【参考方案1】:

通过检查日志确保 c3p0 确实在启动。由于某种原因,我的类路径上有两个版本的休眠(hibernate-core3.3.1.jar 和 hibernate-3.2.6GA.jar)。我还使用了与 3.2.x 不兼容的休眠注释版本 3.4.0GA。 (不知道这是否与原始问题有关)。 在删除了一个休眠 jar(不记得我删除了哪个,可能是 hibernate-3.2.6GA.jar)后,c3p0 终于启动了,我摆脱了 8 小时不活动后发生的烦人的 com.mysql.jdbc.exceptions.jdbc4.CommunicationsException .

【讨论】:

我们使用的是 Hibernate 3.2.6 Hibernate,带有 3.4.0GA Hibernate 注释,我们没有任何明显的异常(只有在 8 小时后处理 c3p0 时才会出现这些问题,还是我们会另行通知)。我们看到 C3P0 在我们的日志中被配置和使用(一旦我使用 c3p0.properties 开启登录),例如"[INFO] 正在初始化 c3p0 池... com.mchange.v2.c3p0.PoolBackedDataSource ... idleConnectionTestPeriod -> 20, , maxIdleTime -> 60..." 尝试将hibernate升级到3.3.X,hibernate不支持上述组合。 (或降级休眠注释) 它现在似乎可以工作了我不必升级到 3.3.X,我们可以使用注释 3.4.0 保持在 3.2.6,除非 Maven 正在以一种奇怪的方式解决依赖关系方式。我确实将 hibernate.properties 更改为: hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider hibernate.c3p0.max_size=100 hibernate.c3p0.min_size=10 hibernate.c3p0.timeout=5000 hibernate.c3p0.max_statements=100 hibernate.c3p0.idle_test_period=300 hibernate.c3p0.acquire_increment=2 好的,很有趣。据我所知,您添加的唯一内容是 hibernate.connection.provider_class=org.hibernate.connection.C3P0ConnectionProvider ? 我知道我在这个问题上很迟钝,但这对寻找答案的人可能很有用:似乎这个 provider_class 参数是在 3.2 中添加的,现在是必需的,但没有太多文档记录。见agileapproach.com/blog-entry/…

以上是关于Hibernate c3p0 连接池不会超时空闲连接的主要内容,如果未能解决你的问题,请参考以下文章

c3p0 连接池

c3p0 数据库连接池

c3p0连接池的使用

spring02

Hibernate、C3P0、Mysql——断管

hibernate中如何使用c3p0连接池?