Duvida sobre Orientação a Objetos

Olá,

Estive analisando o codigo java dos botões CRUD de minha aplicação. Notei que é criado uma nova conexão a cada clique de botão que, depois é fechada em um finally.

public ActionForward perform_select_action(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(true); ActionForward actionForward = null; com.teste.util.jdbc.JdbcUtil j = null; try { j = new com.teste.util.jdbc.JdbcUtil(); j.setMaxRows(500); try { select_action(j, mapping, form, request, response); } finally { } actionForward = mapping.findForward("same"); } catch (Exception e) { ActionErrors errors = new ActionErrors(); errors.add("ActionErrors.GLOBAL_ERROR_bl_form_Adm_bairro", new ActionError("error.action.exception",com.teste.util.system.Error.getMessage(e))); request.setAttribute(org.apache.struts.Globals.ERROR_KEY, errors); session.setAttribute("exception", com.teste.util.system.Error.getDescription(e)); actionForward = mapping.findForward("same"); } finally { if (j != null) { j.close(); } } return actionForward; }

Alterei o código de maneira que evitasse a criação da variavel ‘j’ no linha 4 do acima. O Codigo funcionou normalmente e ficou assim:

public ActionForward perform_select_action(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(true); ActionForward actionForward = null; //com.teste.util.jdbc.JdbcUtil j = null; try { //j = new com.teste.util.jdbc.JdbcUtil(); //j.setMaxRows(500); try { select_action((com.teste.util.jdbc.JdbcUtil) new com.teste.util.jdbc.JdbcUtil(), mapping, form, request, response); } finally { } actionForward = mapping.findForward("same"); } catch (Exception e) { ActionErrors errors = new ActionErrors(); errors.add("ActionErrors.GLOBAL_ERROR_bl_form_Adm_bairro", new ActionError("error.action.exception",com.teste.util.system.Error.getMessage(e))); request.setAttribute(org.apache.struts.Globals.ERROR_KEY, errors); session.setAttribute("exception", com.teste.util.system.Error.getDescription(e)); actionForward = mapping.findForward("same"); } finally { // if (j != null) { // j.close(); // } } return actionForward; }

Metodo j.close(), do finally do Primeiro Codigo:

public void close() { try { if (conn != null) { conn.close(); } if (initCtx != null) { initCtx.close(); } } catch (Exception e) { com.teste.util.logger.Logging.log("com.teste.util.jdbc", java.util.logging.Level.INFO, JdbcUtil.class.getName() + ".JdbcUtil()[206]", e); } }

Vamos as duvidas:
1 - O segundo código é mais rápido que o primeiro ?
2 - No primeiro codigo, Oque acontence com a variavel ‘j’ quando é fechada no finally, Automaticamente é removida da Memoria ?
3 - Não existe uma variavel especifica para abrigar o objeto da conexão e mesmo assim funcionou. Oque realmente acontence no codigo abaixo(linha 9) ?

select_action((com.teste.util.jdbc.JdbcUtil) new com.teste.util.jdbc.JdbcUtil(), mapping, form, request, response);

Obrigado!

Seguinte com essa alteração no codigo vc esta criando varias conexoes que nao estam sendo fechadas, para fechar a conexão e destruir a instacia do objeto vc precisa de uma refencia do mesmo, deixo o codigo como estava mais adicione essa linha depois do

j.close;
j =null;

Não é necessário fazer j = null. Quando a variável sair de escopo, ele se tornará coletável.

É importante sempre fechar conexões, statements e resultsets num finally. Caso contrário, você pode ter memory leaks na sua aplicação.

Para resolver o problema de criar conexões (que é um processo lento) use um Pool de conexões. Ele fará a gerência e o reaproveitamento das conexões para você de uma maneira segura.

O que não pode é abrir uma conexão uma vez só, e esperar reusa-la sempre. Isso não só gera um leak, como também não é thread-safe.

Na verdade já uso pool de conexões, estou na duvida é se a cada botão do CRUD tenho que estanciar uma nova conexão. Na linha 6 do primeiro codigo o retorno do metodo é um getConnection do Pool.

È que segundo este artigo, http://imasters.uol.com.br/artigo/15285/javaweb/praticas_de_aplicativos_web_com_java/ , não é muito legal abrir uma novo conexão para cada botão de CRUD, dai surgiu a duvida.

Sim, mas no o pool impede que isso aconteça. O que o pool faz é o seguinte:

A primeira vez que o getConnection() é usado, abre-se uma conexão.
Quando você fecha a conexão, ela não é destruída. Ela simplemente volta para o pool.

Quando um novo getConnection() é dado, a conexão que já está aberta e pronta é retornada. Sem nova abertura.

Se a conexão ficar aberta e ociosa por muito tempo, ela é fechada.

O pool também pode abrir mais de uma conexão, caso uma delas já esteja ocupada. É o caso de multiplas threads acessando o banco, por exemplo.

Aliás, o próprio artigo que vc indicou dá como solução do problema de abrir e fechar conexões várias vezes o uso do Pool. Se você já usa o pool, então não tem problema por ali. :slight_smile:

Entendi, :slight_smile:

O objeto InitialContext precisa ser fechado toda fez que a conexão com o pool é fechada ?