Você que trabalha com Grails e MySQL já topou com excessões como estas: “com.mysql.jdbc.CommunicationsException: Communications link failure“, “java.net.SocketException: Broken pipe” , “java.io.EOFException: Can not read response from server. Expected to read 4 bytes, read 0 bytes before connection was unexpectedly lost.” ?
Normalmente ocorrem após algumas horas de inatividade da sua aplicação. Normalmente acontecem porquê o MySQL fecha as conexões inativas, algumas das quais eram justamente as do seu projeto. Há duas soluções para o problema: uma porca e outra elegante.
A porca é simplesmente não fazer nada: ao mandar recarregar novamente a página será recriada a conexão com o MySQL e parecerá que o problema foi resolvido.
A elegante é alterar a seção dataSource do arquivo grails-app/conf/DataSource.groovy para que fique parecido com o exemplo abaixo:
dataSource { pooled = true driverClassName = "com.mysql.jdbc.Driver" username = "seu_usuario" password = "sua_senha" properties { maxActive = 50 maxIdle = 25 minIdle = 5 initialSize = 5 minEvictableIdleTimeMillis = 60000 timeBetweenEvictionRunsMillis = 60000 maxWait = 10000 validationQuery = "/* ping */" } }
A diferença é a seção properties. Nela basta incluir as configurações do pool de conexões do Hibernate. Por deafult, o Hibernate utiliza como gerenciador de pool de conexões o C3P0 que, por sua vez, evita que você obtenha uma conexão inválida com o banco de dados.
Agora, explicando os parâmetros:
maxActive: número máximo de conexões abertas e ativas com o SGBD
maxIdle: número máximo de conexões em stand by que você quer manter
initialSize: número inicial de conexões com o banco de dados
minEvictableIdleTimeMillis: tempo mínimo em milisegundos para que o pool de conexões comece a fechar conexões em idle
timeBetweenEvictionRunsMillis: o tempo entre as limpezas de conexão em milisegundos
maxWait: tempo máximo de espera em milisegundos para se obter uma conexão ou de espera de resultado de uma conexão
validationQuery: qualquer comando a ser enviado para o SGBD apenas para verificar se a conexão está válida ou não.
E é isto: agora seus usuários (e você) não verão mais aquela maldita mensagem de erro ao acessar seu sistema pela manhã
Resolvemos este problema a pouco tempo desta forma.
É como se o mysql fechasse uma conexao que tah na fila (pool) e ela nao saisse da fila.
Parabens por compartilhar com todos! :)
Oi Wanderson, valeu!
Na realidade, é exatamente isto que você descreveu que acontece. O MySQL tem um tempo limite de vida para todas as conexões estabelecidas (é possível alterar este tempo no arquivo my.cnf ou my.ini dependendo da sua distribuição do SGBD inclusive).
O problema é que nem sempre podemos alterar estas configurações. Sendo assim, o que acontece: após um tempo x, o MySQL pensa (e ele está correto nesta lógica) que aquela conexão não tem mais utilidade e simplesmente a mata. O problema é que a aplicação cliente ainda acredita ter uma conexão válida. Sendo assim, no momento em que vai fazer uma consulta ou enviar um comando para o SGBD, da de cara com uma conexão inválida.
Como nem sempre podemos definir o tempo de vida de uma conexão no servidor, esta é a melhor alternativa que conheço.
Esse problema só acontece com o MySQL ou acontece com o Postgres também?
Na realidade pode acontecer com qualquer SGBD
Entao é sempre bom ter essas configurações?!
Muito bom, parabéns.
Altamente recomendado! Valeu!
nice muito bom tava ter esses bugs
é só colocar esse mesmo código no arquivo?
ou tem que fazer alguma modificação?
qual tempo a app pode ficar inativa sem da erro depois de usar esse codigo?
Só precisa alterar o driver caso seja um banco diferente do MySQL.
A aplicação após isto pode ficar inativa o tempo que for.
Boa tarde,
Como eu consigo colocar essa propriedades no hibernate?
Utilizando o c3po ?
Oi Davi, estas dúvidas eu costmo resolver no Grails Brasil (http://www.grailsbrasil.com.br).
Rola de você postar a dúvida por lá?