Problemas com pool de conexões do tomcat

12 respostas
J

Estou debugando uma aplicação que faz vários acessos ao banco de dados e num determinado momento recebo estes erros:

FATAL: sorry, too many clients already

A aplicação continua rodando, mesmo depois do erro, só que mais lenta e com alguns bugs e depois de um tempo recebo este erro:

Cannot get a connection, pool error Timeout waiting for idle object

Vendo o código vi que em toda operação que é feita no banco ele o programa abre e fecha uma conexão com o mesmo. As conexões sao feitas através do tomcat ele que gerencia o pool.
O problema pode estar ai? Quando o programa abre e fecha as conexões quando faz uma operação no banco?

12 Respostas

P

Veja se a aplicação esta usando algum Data Source mesmo, se sua conexão estiver sendo feita na mão pode estar abrindo o bico mesmo, poste a forma que vc esta usando sua conexão.

J

Sim a conexão é feita através de um datasource.
E a conexão é obtida através de uma classe factory. Dentro da classe factory tem um atributo estático que é instanciado uma única vez e ai só ficar retornando as conexões, abaixo segue a parte do código que faz estas tarefa:

public static Connection getConnectionTomcat() throws NamingException, SQLException{
                if(DATASOURCE == null){
                        DATASOURCE = (DataSource) new InitialContext().lookup("java:/comp/env/jdbc/database");
                }
                return DATASOURCE.getConnection();
        }

E na DAO a chamada para executar uma determinada tarefa no banco é feita assim:

Connection conn = ConnectionFactory.getConnectionTomcat();
                        PreparedStatement statement = conn.prepareStatement(query);
                        statement.setInt(1, moQueue.getProcessed());
                        statement.setInt(2, moQueue.getQueueId());
                        int rowsAffected = statement.executeUpdate();
                        this.getLogger().info(this.getToken() + " Query: " + this.stm.toString());
                        statement.close();
                        conn.close();
                        statement = null;
                        conn = null;

Sendo que são chamados vários métodos parecidos com este código acima e a aplicação ainda é multi-thread, pq ela precisa ser rápida para atualizar os dados e retornar os mesmo.
Teria alguma forma de resolver este erro?

P

Crie um método closeConnection mais ou menos assim:

public void closeConnection  (
	        Connection conn,
	        PreparedStatement stmt,
	        ResultSet rs) throws Exception {
	        if (rs != null) {
	            try {
	                rs.close();
	            } catch (SQLException e) {
	            	throw e;
	            }
	        }
	        if (stmt != null) {
	            try {
	                stmt.close();
	            } catch (SQLException e) {
	            	throw e;
	            }
	        }
	        if (conn != null) {
	            try {
	                conn.close();
	                logger.info("Close Conn - "+conn.hashCode()+conn.toString());
	            } catch (SQLException e) {
	            	throw e;
	            }
	        }
}

E nos seus DAOS chame em um bloco finaly forçando fechar a conexão

try{
}catch (SuaExcecao e){
//seu tratamento de erro   
} finally {
	connectionFactory.closeConnection(conn, pstmt, rs);
}
J

Blz, eu fiz o método mas não entendi como isso iria resolver o meu problema…
Poderia dar uma explicação, por favor?

P

Esse finaly força a fechar as conexoes que podem estar penduradas na sua aplicação, além disso é possível aumentar o numero de conexoes permitidas no poll, veja se esta definido alguma coisa em maxactive:

http://tomcat.apache.org/tomcat-6.0-doc/jndi-datasource-examples-howto.html

J

Quando é feita a chamada na “mão”, sem usar o método, como eu estava fazendo antes não funciona?
E context.xml está configurado desta maneira, coloquei estes valores altos, para teste e para tentar acabar com os erros:

maxActive="1000" maxIdle="700" maxWait="30000"

E outra coisa eu tenho métodos que retornam alguns dados do banco, e por causa disso eu uso o bloco try/cath fora do método, qual seria a melhor opçção deixar o bloco dentro do métdo ou chamar um throws no método?

P

Prefiro deixar dentro do proprio metodo nesse caso especifico.

J

Comecei a fazer os testes com o código atualizado e agora só recebo este erro:

J

Consegui resolver este erro:

FATAL: sorry, too many clients already

O erro era q o banco estava configurado para ter só 100 conexões, ai aumentei o mesmo para 500 conexões, sendo que apareceu outro erro, q este:

Cannot get a connection, pool error Timeout waiting for idle object

E eu já coloquei o código para forçar a matar a conexão alguém sabe alguam solução ou já passou por isso?

J

Descobri o porque do erro

FATAL: sorry, too many clients already

A aplicação possui várias threads e estas threads se conectam no banco e executam querys, com isso mata o pool de conexões, gostaria de saber se tem como contornar este erro configurando sõ o context.xml ou se existe alguma outra maneira de deixar a conexão em cache?

P

Tenta setar estas configurações, dependendo da aplicação será necessário ajustar alguns parametros.
Mais no meu caso o que nada resolvia, os parametros abaixo atenderam.

Jedi_FeniX:
Estou debugando uma aplicação que faz vários acessos ao banco de dados e num determinado momento recebo estes erros:

FATAL: sorry, too many clients already

A aplicação continua rodando, mesmo depois do erro, só que mais lenta e com alguns bugs e depois de um tempo recebo este erro:

Cannot get a connection, pool error Timeout waiting for idle object

Vendo o código vi que em toda operação que é feita no banco ele o programa abre e fecha uma conexão com o mesmo. As conexões sao feitas através do tomcat ele que gerencia o pool.
O problema pode estar ai? Quando o programa abre e fecha as conexões quando faz uma operação no banco?

H

Olá,
Estou com o mesmo problema…

"Cannot get a connection, pool error Timeout waiting for idle object "

Funcionou com estas configurações?

Criado 5 de janeiro de 2009
Ultima resposta 19 de nov. de 2010
Respostas 12
Participantes 4