在MySQL,Grails 2应用程序更长时间不活动期间保持池连接活动(或将它们计时并获得新的连接)的正确方法

问题描述 投票:36回答:2

我有一个grails应用程序,有高活动的flurries,但往往是一段时间不活动,可以持续几个小时到一个晚上。我注意到早上的第一批用户得到以下类型的异常,我相信这是由于池中的连接过时而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)
mysql grails connection-pooling connector-j
2个回答
34
投票

最简单的方法是配置连接池以指定在将连接传递给应用程序之前运行的查询以测试连接:

validationQuery="select 1 as dbcp_connection_test"
testOnBorrow=true

可以在其他事件上运行相同的“连接验证”查询。我不确定这些的默认值:

testOnReturn=true
testWhileIdle=true

还有一些配置设置可以限制池中空闲连接的“年龄”,如果在服务器端关闭空闲连接,这可能很有用。

minEvictableIdleTimeMillis
timeBetweenEvictionRunsMillis

http://commons.apache.org/dbcp/configuration.html


8
投票

我不知道它是否是处理数据库连接的最佳方式,但我遇到了与您描述的问题相同的问题。我尝试了很多,最后得到了c3p0 connection pool

使用c3p0可以强制您的应用在一段时间后刷新数据库连接。

c3p0.jar放入lib文件夹,并将配置添加到conf/spring/resources.groovy

我的resources.groovy看起来像这样:

import com.mchange.v2.c3p0.ComboPooledDataSource
import org.codehaus.groovy.grails.commons.ConfigurationHolder as CH

beans = {
    /**
    * c3P0 pooled data source that forces renewal of DB connections of certain age
    * to prevent stale/closed DB connections and evicts excess idle connections
    * Still using the JDBC configuration settings from DataSource.groovy
    * to have easy environment specific setup available
    */
    dataSource(ComboPooledDataSource) { bean ->
        bean.destroyMethod = 'close'
        //use grails' datasource configuration for connection user, password, driver and JDBC url
        user = CH.config.dataSource.username
        password = CH.config.dataSource.password
        driverClass = CH.config.dataSource.driverClassName
        jdbcUrl = CH.config.dataSource.url
        //force connections to renew after 4 hours
        maxConnectionAge = 4 * 60 * 60
        //get rid too many of idle connections after 30 minutes
        maxIdleTimeExcessConnections = 30 * 60
    }
 }  
© www.soinside.com 2019 - 2024. All rights reserved.