【发布时间】:2010-11-25 09:28:05
【问题描述】:
我们有一个 java 服务器连接到 MySQL 5 数据库,使用 Hibernate 作为我们的持久层,它使用 c3p0 进行数据库连接池。
我已尝试遵循 c3p0 和 hibernate 文档:
我们在生产服务器上收到一个错误,指出:
... 原因: 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)
标签: database hibernate database-connection connection-pooling c3p0