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