Falha de comunicação com o banco depois de um tempo

7 respostas
rafa120

Ola! Não achei o lugar certo onde postar a minha dúvida, então vai no Java Básico mesmo… rs

Tem lá o sistema na máquina e quando inicio o tomcat funciona tudo ok entre o sistema e o banco. Mas depois de algumas horas a comunicação é perdida e não consigo nem logar mais no sistema (abre o site, mas não comunica com o banco). Se eu for direto no banco de dados está normal.
Se eu reiniciar o tomcat o a comunicação com o banco volta.
O que poderia ser? algum problema no banco ou no meu código? ou o tomcat com algum problema?

A máquina com o sistema é Ubuntu 32bits

Nela tem um servidor Apache PHP que tem um sistema PHP que funciona normal.

Ambos bancos de dados estão no MySQL 5.5.24 (penúltima versão)
O meu connector-java é 5.1.22 (última versão)

7 Respostas

acesar

Tive um problema similar uma vez e resolvi utilizando o C3P0 http://sourceforge.net/projects/c3p0/… No meu caso estou usando o hibernate como framework ORM e banco MySql 5.1 e as configurações do C3P0 ficam no hibernate.cfg.xml.

Abs

rafa120

Hmm… interessante

teria algum exemplo de como fazer em jdbc? o meu sistema eh simples… jsp e servlets

rafa120

não consegui achar ainda… soh acho pra hibernate =/

E

Conexões de bancos de dados não devem ficar abertas por muito tempo. Normalmente os bancos derrubam essas conexões que ficam inativas durante muito tempo.

Pools de conexões normalmente têm algumas configurações que permitem que as conexões do pool fiquem abertas indefinidamente porque elas mandam periodicamente alguns comandos (como SELECT SYSDATE FROM DUAL; no caso do Oracle ou outra coisa parecida, no caso do MySQL).

Portanto, mesmo que você não julgue necessário usar pools, use-os porque eles têm essas configurações que ajudam bastante a ter sistemas que rodam por longos períodos.

E

rafa120:
Hmm… interessante

teria algum exemplo de como fazer em jdbc? o meu sistema eh simples… jsp e servlets

No JDBC você não tem de mudar quase nada (a menos do fato que você tem de pegar a conexão do pool, em vez de criar explicitamente a conexão, e devolver a conexão logo depois que esta foi usada).

Você tem de configurar o pool de conexões, e há um monte de tutoriais na Internet para fazer isso.

rafa120

Eu achei este tutorial: http://netbeando.blogspot.com.br/2009/03/broken-pipe-solucao-correta.html

Porém gostaria de uma ajudinha de como implementar isso no meu codigo, por favor

eu tenho um banco.properties que contem:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost/meubanco
usuario=user
senha=pass
numeroMaximoConexoes=100

e tenho a classe pool

public class Pool implements InterfacePool{
    
    private InterfaceDataSource ds;
    private ArrayBlockingQueue<Connection> conexoesLivres;
    private HashMap<String, Connection> conexoesUtilizadas;
    private Integer numeroMaximoConexoes;
    private ResourceBundle config;
    
    public Pool() throws SQLException{
        config = ResourceBundle.getBundle("br.com.changes.conexao.banco");
        ds = new DataSource(config.getString("url"), config.getString("driver"), config.getString("usuario"), config.getString("senha"));
        numeroMaximoConexoes = Integer.parseInt(config.getString("numeroMaximoConexoes"));
        conexoesLivres = new ArrayBlockingQueue<Connection>(numeroMaximoConexoes, true);
        conexoesUtilizadas = new HashMap<String, Connection>();
    }
    
    @Override
    public Connection getConnection() {
        
        Connection con = null;
        
        try {
            if (conexoesUtilizadas.size() < numeroMaximoConexoes) 
            {
                con = conexoesLivres.poll();
                if (con == null)
                    con = ds.getConnection();
                else if (con.isClosed())
                {
                    this.getConnection();
                }
                conexoesUtilizadas.put(con.toString(), con);
            }
        } catch (SQLException e) {
            System.out.println("Problemas com o Pool");
            e.printStackTrace();
        }
        
        return con;
    }
    
    @Override
    public void liberarConnection(Connection con) {
        conexoesLivres.add(con);
        conexoesUtilizadas.remove(con.toString());
    }  
    
}
rafa120

entanglement:
Conexões de bancos de dados não devem ficar abertas por muito tempo. Normalmente os bancos derrubam essas conexões que ficam inativas durante muito tempo.

Pools de conexões normalmente têm algumas configurações que permitem que as conexões do pool fiquem abertas indefinidamente porque elas mandam periodicamente alguns comandos (como SELECT SYSDATE FROM DUAL; no caso do Oracle ou outra coisa parecida, no caso do MySQL).

Portanto, mesmo que você não julgue necessário usar pools, use-os porque eles têm essas configurações que ajudam bastante a ter sistemas que rodam por longos períodos.

Então se eu colocar um SELECT SYSDATE() FROM DUAL; no meu sistema, vai resolver o problema?

Criado 23 de novembro de 2012
Ultima resposta 28 de nov. de 2012
Respostas 7
Participantes 3