conectar - mysql connector java
Forma correcta de mantener las conexiones agrupadas con vida(o agotarlas y obtener nuevas) durante una inactividad más prolongada para MySQL, aplicación Grails 2 (2)
Lo más fácil es configurar el grupo de conexiones para especificar la consulta que se ejecutará para probar la conexión antes de pasarla a la aplicación:
validationQuery="select 1 as dbcp_connection_test"
testOnBorrow=true
Esta misma consulta de "validación de conexión" se puede ejecutar en otros eventos. No estoy seguro de los valores predeterminados para estos:
testOnReturn=true
testWhileIdle=true
También hay configuraciones que limitan la "edad" de las conexiones inactivas en el grupo, lo que puede ser útil si las conexiones inactivas se cierran en el extremo del servidor.
minEvictableIdleTimeMillis
timeBetweenEvictionRunsMillis
Tengo una aplicación Grails que tiene ráfagas de alta actividad, pero a menudo períodos de inactividad que pueden durar varias horas o más de la noche. Noté que los primeros usuarios de la mañana reciben el siguiente tipo de excepción, y creo que esto se debe a que las conexiones en el grupo se estancaron y la base de datos MYSql las está cerrando.
He encontrado información conflictiva en Google sobre si el uso de la propiedad de conexión de Connector / J ''autoReconnect = true'' es una buena idea (y si el cliente todavía recibirá una excepción incluso si la conexión se restablece) o si se configura otras propiedades que desalojarán o actualizarán periódicamente las conexiones inactivas, probarán en préstamo, etc. Grails usa DBCP debajo. Actualmente tengo una configuración simple como la que se muestra a continuación, y estoy buscando una respuesta sobre la mejor manera de garantizar que cualquier conexión tomada fuera de la agrupación después de un largo período de inactividad sea válida y no se cierre.
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?
}
}
Excepción
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)
No sé si es la mejor manera de manejar la conexión a la base de datos, pero tuve los mismos problemas que me planteó. Intenté mucho y terminé con el grupo de conexiones c3p0 .
Con c3p0, puede forzar a su aplicación a actualizar la conexión de la base de datos después de un tiempo determinado.
Coloque el c3p0.jar
en su carpeta lib
y agregue su configuración a conf/spring/resources.groovy
.
Mis resources.groovy
ve así:
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
}
}