Java + Tomcat, conexão de banco de dados morrendo?
Pergunta
Eu tenho uma configuração de instância do Tomcat, mas a conexão com o banco de dados que configurei em context.xml
continua morrendo após períodos de inatividade.
Quando verifico os logs, recebo o seguinte erro:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException:O último pacote recebeu com sucesso do servidor foi 68051 segundos atrás.O último pacote enviado com sucesso para o servidor foi de 68051 segundos atrás, o que é mais longo que o valor configurado do servidor de 'wait_timeout'.Você deve considerar a validade da conexão de expiração e/ou teste antes do uso em seu aplicativo, aumentando os valores configurados do servidor para o tempo limite do cliente ou usando a propriedade Connector/J Conexão 'AutoreConnect = true' para evitar esse problema.
Aqui está a configuração em context.xml:
<Resource name="dataSourceName"
auth="Container"
type="javax.sql.DataSource"
maxActive="100"
maxIdle="30"
maxWait="10000"
username="username"
password="********"
removeAbandoned = "true"
logAbandoned = "true"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://127.0.0.1:3306/databasename?autoReconnect=true&useEncoding=true&characterEncoding=UTF-8" />
estou usando autoReconnect=true
como o erro diz para fazer, mas a conexão continua morrendo.Eu nunca vi isso acontecer antes.
Também verifiquei se todas as conexões do banco de dados estão sendo fechadas corretamente.
Solução
DBCP usa o pool de conexões de banco de dados Jakarta-Commons.Baseia-se em vários componentes do Jakarta-Commons:
* Jakarta-Commons DBCP
* Jakarta-Commons Collections
* Jakarta-Commons Pool
Este atributo pode ajudá-lo.
removeAbandonedTimeout="60"
Estou usando o mesmo conjunto de conexões e estou definindo essas propriedades para evitar que a mesma coisa não seja configurada através do Tomcat.Mas se a primeira coisa não funcionar, tente isso.
testWhileIdle=true
timeBetweenEvictionRunsMillis=300000
Outras dicas
Apenas para esclarecer o que realmente está causando isso.Por padrão, o MySQL encerra conexões abertas após 8 horas de inatividade.No entanto, o pool de conexões do banco de dados manterá as conexões por mais tempo.
Portanto, ao definir timeBetweenEvictionRunsMillis=300000 você está instruindo o pool de conexões a executar conexões e despejar e fechar aquelas inativas a cada 5 minutos.
A opção removeAbandoned está obsoleta a partir do DBCP 1.2 (embora ainda presente no ramo 1.3). Aquié uma explicação não oficial.
Não sei se a resposta acima faz basicamente a mesma coisa, mas alguns de nossos sistemas usam a conexão de banco de dados uma vez por semana e vi que fornecemos um sinalizador -Otimeout ou algo desse tipo ao mysql para definir a conexão tempo esgotado.