Data

29 mar, 2011

Solucionando o erro Communication link failure usando Hibernate com Pool + Mysql

Publicidade

Olá, pessoal!

Hoje vou apresentar como resolver o problema abaixo quando temos nossa aplicação em produção e onde apostaríamos tudo que estava ok, pois em teste você nunca tinha visto a seguinte exceção. Mas por que em produção ela aparece, e o cliente liga dizendo que está dando erro?

Bem, eu sofri muito com essa exceção, pesquisei bastante e encontrei várias dicas, mas nenhuma delas conseguia resolver o meu problema. Conversando com Edson Gonçalves, ele me passou dois links importantes e então eu encontrei a solução! Um está em inglês e outro é da Caelum explicando um outro problema, também muito comum, o broken pipe.

Como a única referência que realmente resolvia meu problema era em inglês, já que nunca encontrei nada em português que fosse tão direto e objetivo, resolvi fazer este artigo. Assim, agora temos uma solução direta para o problema, e não apenas discussões e opiniões de como resolver (não que isso não seja útil, mas realmente senti muita necessidade de ter algo mais prático!) 

Let’s go…

Por que temos essa exceção em ambiente de produção?

A resposta é bem simples: se a conexão com seu banco ficar inativa por mais de 8 horas, no caso do MySql, então o banco mata a conexão, e quando o cliente tentar usar, com o pool de conexão, já será tarde demais.

Solucionando

Aqui estou usando o pool de conexão que é exigido em qualquer aplicação JEE, até por questão de manutenção, porém vou limitar o código apenas para meu arquivo context.xml.

Abra seu arquivo context.xml que faz o pool de conexão. Você deve deixá-lo como o código a seguir:

<Context path="/">
<Resource auth="Container"
name="jdbc/bloglpjava"
driverClassName="com.mysql.jdbc.Driver"
maxActive="20" maxIdle="10" maxWait="-1"
type="javax.sql.DataSource"
url="jdbc:mysql://www.camilolopes.com.br/suaplicacao?autoReconnect=true"
password="senha"
username="camilolopes"
validationQuery="SELECT 1"
testOnBorrow="true"
testWhileIdle="true"
timeBetweenEvictionRunsMillis="10000"
minEvictableIdleTimeMillis="60000"
/>
</Context>

O código anterior era assim:

<Context path="/">
<Resource auth="Container"
name="jdbc/bloglpjava"
driverClassName="com.mysql.jdbc.Driver"
maxActive="20" maxIdle="10" maxWait="-1"
type="javax.sql.DataSource"
url="jdbc:mysql://www.camilolopes.com.br/suaplicacao?autoReconnect=true"
password="senha"
username="camilolopes"/>
</Context>

Depois disso, envie xml para produção, dar um restart no servidor e testa. Aqui resolveu. Até que fim.

Bem, espero ter ajudado!

Abraços, see ya!!