É uma boa prática sempre fechar a conexão após um select, update...?

7 respostas
L

Encontrei um tópico onde tinha uma dúvida parecida com esta que tenho, mas não conseguiu resolver. --> [url]http://www.guj.com.br/posts/list/57125.java[/url]

De acordo com os exemplos que vejo e as dicas do meu professor são que sempre que uma instrução (select, update...) for executada, via JDBC, a conexão tem que ser fechada sempre (dentro do método).

O resultSet e o PreparedStatement eu sempre fecho, mas o Connection costumo fechar somente quando não preciso mais do objeto do tipo UsuarioDaoImp (neste caso). Contumava fazer isso quando era aplicação desktop usando swing, mas com aplicação web usando JSF eu não sei.

Info: O banco de dados que uso é MySQL.

Veja:
public class UsuarioDaoImp implements UsuarioDao {

    private Connection conn = null;

    public UsuarioDaoImp() throws Exception{
        conn = new Conectar(
                "com.mysql.jdbc.Driver",
                "jdbc:mysql://localhost/livraria?user=root&password=").getConector();
    }

public int insert(Usuario usu) throws Exception{
        int number;
        PreparedStatement ps = null;
        Connection conn = null;

        if(usu == null){
            throw new Exception("O valor passado não pode ser nulo");
        }
        try{
            String sql = "INSERT INTO aluno " +
                         "(id, usuario, senha) " +
                         "VALUES (?,?,?)";
            conn = this.conn;
            ps = conn.prepareStatement(sql);

            ps.setInt(1, usu.getId());
            ps.setString(2, usu.getUsuario());
            ps.setString(3, usu.getSenha());

            number = ps.executeUpdate();
            ps.close();

        }catch(SQLException ex){
            throw  new SQLException(ex);
        }catch (Exception ex){
            throw  new Exception(ex);
        }finally{
            conn.close(); // --> Sempre tenho que fechar a conexão aqui? é uma boa prática?
	//Fiz uns testes e verifiquei que sempre que fecho esta conexão o objeto de escopo global conn também é fechado de forma automática.
        }
        return number;
    }

Minha aplicação web pode ficar mais lenta se a cada instrução (select, update...) que for feita equivaler a uma chamada do método getConnection(), certo? A saída que tive foi não fechar a conexão dentro da classe, mas acho que quando a página web é fechada, a conexão deve ficar aberta ou perdida porque eu não a fechei. Correto?

Como poderia resolver este problema?

Obrigado

7 Respostas

S

o ideal seria você abrir e fechar a conexao em um classe de controle, na sua classe de presistencia você só fecha o resultset.

exemplo:

Na classe na camada de controle (AtendenteControle)

public void atualizarAtendenteSelecionado() {

abrirConexao();

Atendente atendenteSelecionado = dao.pesquisaPorCodigo(atendenteVO);

fecharConexao();

this.setAtendente(atendenteSelecionado);

}

Na classe de Persistencia camada DAO (AtendenteDAO):

public Atendente pesquisaPorCodigo(Atendente objeto) {

Atendente atendente1 = new Atendente();

ResultSet rst = null;

try {

query = "SELECT matricula_atendente,nome_atendente " +

“FROM tb_atendente WHERE matricula_atendente = '” + objeto.getMatricula_atendente() + "’ ";
rst = stmt.executeQuery(query);
        while (rst.next()) {
            atendente1.setMatricula_atendente(rst.getString(1));
            atendente1.setNome_atendente(rst.getString(2));
        }
        rst.close();
    } catch (SQLException e) {
        e.printStackTrace();
        try {
            rst.close();
        } catch (SQLException ex) {
            ex.printStackTrace();
        }
    }
    return atendente1;
}
S

ou melhor poderia ser utilizado um framework para gerenciamento de transcoes como o spring etc…

L

Obrigado pela ajuda surfzera.

Na primeira o seu conselho foi abrir e fechar, ou seja, fazer o gerenciamento das conexões nas classes de controller e não nas classes DAO, como tenho feito, certo?

Logo no início estava pensando em fazer deste jeito também. mas fiquei com muita dúvida sobre boas práticas, etc…

Muito obrigado

S

exatamente!

L

Só mais uma coisa

No exemplo que você deu:

public void atualizarAtendenteSelecionado() { abrirConexao(); Atendente atendenteSelecionado = dao.pesquisaPorCodigo(atendenteVO); fecharConexao(); this.setAtendente(atendenteSelecionado); }
Quer dizer que, de uma forma ou de outra terei que fechar a conexão dentro do método, no caso o public void atualizarAtendenteSelecionado(). Como sou novato em aplicações web, você acha que ela ficará mais lenta por ter que abrir e fechar uma conexão sempre que uma instrução for executada? Ou este é o procedimento (abrir e fechar a conexão sempre dentro do método) normal e esperado de uma aplicação web?

Obrigado

B

O normal é que para requisição que chega no servidor, você utilize uma conexão para ela. Em outras palavras, uma conexão por thread em execução.

W

surfzera:
Vai a minha duvida de seu comentario gujeiro amigo…
Como a classe DAO receberia a conexao…teria de passar como parametro ou teria de declarar private Connection conexao = ConexaoDao.getConexao();
na classe DAO?

Criado 1 de agosto de 2009
Ultima resposta 7 de jan. de 2012
Respostas 7
Participantes 4