7

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

我试过遵循 c3p0 和 hibernate 文档:

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

...引起:com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:连接关闭后不允许任何操作。由于潜在的异常/错误,连接被隐式关闭:

开始嵌套异常

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException

MESSAGE:从服务器成功接收的最后一个数据包是 45000 秒前。最后一个成功发送到服务器的数据包是 45000 秒前,比服务器配置的“wait_timeout”值长。您应该考虑在应用程序中使用之前使连接有效性过期和/或测试,增加客户端超时的服务器配置值,或使用连接器/J 连接属性“autoReconnect=true”来避免此问题。

堆栈跟踪:

com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:从服务器成功接收的最后一个数据包是45000秒前。最后一个成功发送到服务器的数据包是45000秒前,比服务器配置的'wait_timeout'值长。您应该考虑在应用程序中使用之前使连接有效性过期和/或测试,增加客户端超时的服务器配置值,或使用连接器/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

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.properties 文件,以确保 c3p0 正确处理连接。

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
4

1 回答 1

2

通过检查日志确保 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 .

于 2009-09-03T19:10:49.760 回答