Grails: resolvendo o problema de queda de conexão com o MySQL

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ã

11 comentários em “Grails: resolvendo o problema de queda de conexão com o MySQL”

  1. wanderson santos

    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! :)

    1. 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.

  2. é 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?

    1. Kico (Henrique Lobo Weissmann)

      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.

Deixe uma resposta

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.

Rolar para cima