我有一个grails应用程序,其中包含大量活动,但随后经常不活动,可能会持续几个小时到一整夜。我注意到早上的第一个用户会收到以下类型的异常,我相信这是由于池中的连接过时并且MYSql数据库关闭了它们。
我在Googling中发现了有关使用Connector / J连接属性’autoReconnect = true’的好主意(以及即使恢复了连接后客户端是否仍然会获得异常)的冲突信息,或者是否设置了冲突信息其他将定期退出或刷新空闲连接,借用测试的属性。Grails在下面使用DBCP。我目前有一个简单的配置,如下所示,我正在寻找一个答案,以期能最好地确保长时间不活动后从池中抢夺的任何连接均有效且未关闭。
dataSource { pooled = true dbCreate = "update" url = "jdbc:mysql://my.ip.address:3306/databasename" driverClassName = "com.mysql.jdbc.Driver" dialect = org.hibernate.dialect.MySQL5InnoDBDialect username = "****" password = "****" properties { //what should I add here? } }
例外
2012-06-20 08:40:55,150 [http-bio-8443-exec-1] ERROR transaction.JDBCTransaction - JDBC begin failed com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: The last packet successfully received from the server was 64,129,968 milliseconds ago. The last packet sent successfully to the server was 64,129,968 milliseconds ago. is longer than the server configured value of 'wait_timeout'. You should consider either expiring and/or testing connection validity before use in your application, increasing the server configured values for client timeouts, or using the Connector/J connection property 'autoReconnect=true' to avoid this problem. at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) at com.mysql.jdbc.SQLError.createCommunicationsException(SQLError.java:1116) at com.mysql.jdbc.MysqlIO.send(MysqlIO.java:3851) ...... Lots more ....... Caused by: java.sql.SQLException: Already closed. at org.apache.commons.dbcp.PoolableConnection.close(PoolableConnection.java:114)
最简单的方法是配置连接池以指定要在将连接传递给应用程序之前运行以测试该连接的查询:
validationQuery="select 1 as dbcp_connection_test" testOnBorrow=true
相同的“连接验证”查询可以在其他事件上运行。我不确定这些默认值:
testOnReturn=true testWhileIdle=true
还有一些配置设置会限制池中空闲连接的“使用期限”,如果在服务器端关闭空闲连接,这将很有用。
minEvictableIdleTimeMillis timeBetweenEvictionRunsMillis
http://commons.apache.org/dbcp/configuration.html