Problemas graves ao encerrar conexoes - Urgente

7 respostas
rfpsatin

Salve pessoal, preciso de uma dica valiosa dos colegas.

Ha um sistema onde trabalho que usa o padrao MVC. (JSP/Servlets/JB).

Bem, o caso eh o seguinte.

todas as paginas jsp “entram em contado com um servlet” q por sua vez direciona a outros servlets… e ae a historia vai athe chegar nos JB.

Bem, toda “computacao” real (iteracao com bd) é feita em vamos dizer assim "JavaBeans Incrementados " :lol: . Nestes programas sao feitas as operacoes como:
Insert,Update,Delete e Select.

O fato eh o seguinte.

Um metodo responsavel por fazer um delete (implementado neste JB) estabelece uma conexao com o BD, faz a operacao e ao termino ele da um close na conexao.! tudo certo neh!? desde que nao haja erro! se houver erro neste meio termo a conexao nao eh fechada e por default todos estes metodos nao tratam excessao, eles lancam para cima (throws SqlException) para o metodos que o chamou(no caso um servlet). La no servlet ele trata a excessao e mostra na tela o erro, contudo, como nao tem acesso ao objeto de conexao este nao eh liberado da memoria(fica la)… nesta medida chega uma hora que nosso banco trava e para!.

Estive mexendo nos codigos um pouco e colocando nos Beans o bloco

try{



}finally{

con.close();

}

e funcionou como o esperado, contudo, imagine fazer isso em mais de 50 000 linhas de codigo?

Vcs estao conseguindo entender meu problema? Conseguem me dar uma solucao mais simples que colocar try…finally em todos os blocos de codigo?

Pessoal, realmente preciso de uma dica.

um abraco a todos… quem puder me dar uma dica, eu agradeco.

at. Ricardo

Para que vcs possam visualizar melhor o problema, vou colocar aqui um trecho do codigo servlet que chama o bean e como ele esta sendo executado no Bean.

Delete…

else if (menu.equals("delete")) {
        StringBuffer errorMsg = new StringBuffer(100);
        if (request.getParameter("cod")!=null) {
          int cod = Integer.parseInt(request.getParameter("cod"));
          try {
            BeneficiarioBeanManager.getInstance().delete(cod,usuarioBean.getCod());
            session.setAttribute("BancoCollection",
                                 BeneficiarioBeanManager.getInstance().
                                 select(1, 20, "BEN_COD"));
          }
          catch (Exception ex) {
            System.out.println(
                "Execao no metodo service(). BeneficiarioServlet");
            //ex.printStackTrace();
            session.setAttribute("exception", ex);
            errorMsg.append(
                "Esse Beneficiário está sendo utilizado em outro Cadastro.<BR>");
            session.setAttribute("erro", errorMsg.toString());
            ServletTools.dispatcherPage(request, response,
                                        "/beneficiario_consulta.jsp?erro");
          }

O Bean que faz o delete:

public void delete(int num,int codUsu) throws SQLException {
    Connection con = null;

    try{
        //pega a conexao com o banco de dados.
        con = source.getConnection();
        con.setAutoCommit(false);
        // executa a querie para alteracao de uma linha da tabela do DB.
        PreparedStatement st = con.prepareStatement(properties.getProperty(
        "beneficiario.updateUsuario"));
        st.setInt(1, codUsu);
        st.setInt(2, num);
        st.execute();
        st.clearParameters();
        st = con.prepareStatement(properties.getProperty("beneficiario.delete"));
        st.setInt(1, num);
        st.execute();
        con.commit();
    }finally{
        con.close();
    }
  }

Estao vendo o try… finally acima? tive que colocar… nao quero ter q fazer isso em todo lugar…

7 Respostas

pcalcado

Cara, a dica número um é centralizar o acesso à banco de dados e outros recursos. A não-tão-famosa regra do SPOT. O que você está vivendo é consequência do projeto ruim. Misturar camadas nunca é boa idéia…

Que eu saiba, não tem jeito.

Aproveita que vai ter que mexer em tudo, e utiliza ao menos o padrão DAO.

Ah, e, na boa, colcoar URGENTE an mensagem não vai fazer qualquer membro tarimbadod ar mais ou menso atenção [alguns dão menos], simplesmente porque é urgente para você, ninguém tem culpa :wink:

[]s

rfpsatin

Sim, comecou desta forma e mudar agora acho que da mais trabalho que colocar um monte de try…finally.

Sera que nao tem outra forma de matar esta conexao qdo der erro?

ps… :smiley: blz sobre o URGENTE. rs…

_fs

Cara, quando ocorrem runtime exceptions, os recursos gastos não são liberados automaticamente?

Você monitorou a coisa toda? Tem certeza que as connections ficam lá?

pcalcado

Você fala especificamente de JDBC? Porque se não, a respsota é não. A conexão deve estar referenciada em algum outro lugar, e o gc não pega, ainda que pegasse, ia demorar mais que dar um close nela. É para isso que temos finally, não? :wink:

[]s

_fs

Tem razão Philip :smiley:

rfpsatin

Eh, to usando JDBC e estou monitorando minhas conexoes com o Banco. Elas realmente ficam lá, e ficam, e ficam :oops: e ficam … :cry: e ficam rs…

rfpsatin

Bom
Pesquisei a documentacão do Resin e encontrei 2 parametros no mínimo
interessantes:

parametro descricao Default

max-active-time Maximum time a connection allowed to be active 6 hours
max-pool-time Maximum time a connection is kept in the pool 24 hours

Fiz alguns testes e ao que parece funcionou perfeitamente… com isso ha tempo para “correcao do fonte” :lol:

:smiley:

abraco

Criado 20 de julho de 2004
Ultima resposta 21 de jul. de 2004
Respostas 7
Participantes 3