Connection Pool Assíncrona

0 respostas
dukejeffrie

O pessoal pediu pra eu explicar que coisa é essa com esse nome doido que eu fiz.

Bom, aqui vai a história. Pra falar com um banco de dados de qualidade duvidosa eu usava um objeto só, e todos os acessos ao banco eram feitos através desse objeto (o bom e velho DBAdapter).

Enquanto era só pra testes, eu tinha aquela variável “Connection conn” e criava todos os statements através dela. Mas quando o servidor começou a rodar por dias e dias, o banco caía e eu não podia fazer nada além de restartar meu servidorzinho. Então quis que ele fosse esperto para resgatar a conexão perdida.

Eu já tinha tido contato com o ConnectionPool do Jakarta, mas a documentação daquele negócio é horrível. Então pensei em fazer meu próprio pool.

Só que o Caché (ops, falei o nome do banco), quando dá pau, não fecha a connection. eu tinha um trecho assim:

if (conn.isClosed()) {
    // joga fora
  conn = createConnection();
  }

Que não funcionava. Para testar se a conexão ainda estava válida, eu precisava fazer:

try {
     Statement st = conn.createStatement();
     st.close();
   }
   catch (SQLException e) {
     // joga fora
     conn = createConnection();
   }

Mas nessa altura, eu já tinha um pool de conexões: uma ArrayList normal, em que eu inseria as conexões por um lado e pegava por outro. Os blocos acima faziam parte do meu método releaseConnection(Connection conn).

Só que os borrows (pra pegar a conexao) e releases (pra soltá-las) aconteciam sempre numa chamada RMI: o cliente ficava esperando eu fazer toda essa palhaçada até o método retornar. Então achei por bem devolver as conexões para o Pool assincronamente, isto é, em outra thread.

Aqui vai o código do método (não se preocupem em entender tudo):

protected void releaseConnection(Connection c) throws SDCException {
        Runnable r = new ConnectionPoolFiller(this, connectionPool, c);
        new Thread(r).start();
    }

    private static class ConnectionPoolFiller implements Runnable {

        private List pool;
        private Connection c;
        private DBFornecedor owner;

        public ConnectionPoolFiller(DBFornecedor owner, List pool, Connection c) {
            this.owner = owner;
            this.pool = pool;
            this.c = c;
        }

        public void run() {
            boolean ok = false;
            if (c != null) {
                synchronized(pool) {
                    ok = giveBack();
                }
            }
            if (!ok) {
                putNew();
            }
            else {
                debug("Connection released asynchronously.");
            }
        }
    }

Tipo, eu tenho um “devolvedor de connections” que roda em uma thread nova. Ainda não é o ideal, mas me serve, ganhei um tempinho no retorno de cada método.

Bom, é isso. Alguém tem comentários?? : )))
[]s

Criado 6 de fevereiro de 2003
Respostas 0
Participantes 1