Diz-se ser um bom hábito fechar todos os recursos JDBC após o uso. Mas se eu tiver o código a seguir, é necessário fechar o conjunto de resultados e a instrução?
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
conn = // Retrieve connection
stmt = conn.prepareStatement(// Some SQL);
rs = stmt.executeQuery();
} catch(Exception e) {
// Error Handling
} finally {
try { if (rs != null) rs.close(); } catch (Exception e) {};
try { if (stmt != null) stmt.close(); } catch (Exception e) {};
try { if (conn != null) conn.close(); } catch (Exception e) {};
}
A questão é se o fechamento da conexão faz o trabalho ou se deixa alguns recursos em uso.
Respostas:
O que você fez é uma prática perfeita e muito boa.
O motivo pelo qual digo boas práticas ... Por exemplo, se por algum motivo você estiver usando um tipo "primitivo" de pool de banco de dados e telefonar
connection.close()
, a conexão será retornada ao pool e oResultSet
/Statement
nunca será fechado e você vai encontrar muitos problemas diferentes!Portanto, você nem sempre pode contar com
connection.close()
a limpeza.Eu espero que isso ajude :)
fonte
O Java 1.7 facilita muito nossas vidas, graças à instrução try-with-resources .
Essa sintaxe é bastante breve e elegante. E
connection
será fechado mesmo quando ostatement
não puder ser criado.fonte
;
)Dos javadocs :
No entanto, os javadocs não são muito claras sobre se o
Statement
eResultSet
estão fechados quando você fecha o subjacenteConnection
. Eles simplesmente afirmam que fechar uma conexão:Na minha opinião, sempre feche explicitamente
ResultSets
,Statements
eConnections
quando você terminar com eles, a implementaçãoclose
pode variar entre os drivers de banco de dados.Você pode salvar um monte de código caldeira-plate usando métodos tais como
closeQuietly
em dbUtils de Apache.fonte
Agora estou usando o Oracle com Java. Aqui está o meu ponto de vista:
Você deve fechar
ResultSet
eStatement
explicitamente porque o Oracle tem problemas anteriormente em manter os cursores abertos, mesmo após o fechamento da conexão. Se você não fechar oResultSet
(cursor), ocorrerá um erro como o máximo de cursores abertos excedido .Eu acho que você pode encontrar o mesmo problema com outros bancos de dados que você usa.
Aqui está o tutorial Fechar ResultSet quando terminar :
fonte
Se você quiser um código mais compacto, sugiro usar o Apache Commons DbUtils . Nesse caso:
fonte
O método correto e seguro para fechar os recursos associados ao JDBC é este (extraído de Como Fechar Recursos JDBC Corretamente - Sempre ):
fonte
Não importa se
Connection
é poolável ou não. Até a conexão com piscina precisa ser limpa antes de retornar à piscina."Limpo" geralmente significa fechar conjuntos de resultados e reverter as transações pendentes, mas não fechar a conexão. Caso contrário, o pool perde o sentido.
fonte
Não, você não precisa fechar nada, exceto a conexão. Por especificações do JDBC, o fechamento de qualquer objeto superior fechará automaticamente os objetos inferiores. O fechamento
Connection
fechará todos osStatement
s criados pela conexão. Fechar qualquerStatement
fechará todos osResultSet
s criados por issoStatement
. Não importa seConnection
é poolável ou não. Até a conexão com piscina precisa ser limpa antes de retornar à piscina.É claro que você pode ter longos loops aninhados na
Connection
criação de muitas instruções e, em seguida, fechá-las é apropriado. Eu quase nunca fechoResultSet
, parece excessivo ao fecharStatement
ouConnection
VAI fechá-los.fonte
Eu criei o seguinte método para criar One Liner reutilizável:
Eu uso esse código em uma classe pai que é herdada de todas as minhas classes que enviam consultas de banco de dados. Eu posso usar o Oneliner em todas as consultas, mesmo se eu não tiver um resultSet. O método cuida de fechar o ResultSet, Statement, Connection na ordem correta. É assim que meu bloco finalmente se parece.
fonte
Tanto quanto me lembro, no JDBC atual, os conjuntos de resultados e as instruções implementam a interface AutoCloseable. Isso significa que eles são fechados automaticamente após serem destruídos ou sair do escopo.
fonte
close
é chamado no final de uma instrução try-with-resources. Consulte docs.oracle.com/javase/tutorial/essential/exceptions/… e docs.oracle.com/javase/8/docs/api/java/lang/AutoCloseable.html .Algumas funções de conveniência:
fonte
Com o formato Java 6, acho melhor verificar se ele está fechado ou não antes do fechamento (por exemplo, se algum pool de conexões expulsar a conexão em outro encadeamento) - por exemplo, algum problema de rede - a instrução e o estado do conjunto de resultados podem ser fechados. (isso nem sempre acontece, mas eu tive esse problema com Oracle e DBCP). Meu padrão é esse (na sintaxe Java mais antiga) é:
Em teoria, não é 100% perfeito, porque entre a verificação do estado fechado e o fechamento em si, há pouco espaço para a mudança de estado. No pior dos casos, você receberá um aviso por muito tempo. - mas é menor que a possibilidade de alteração de estado em consultas de longo prazo. Estamos usando esse padrão na produção com uma carga "média" (150 usuários simultâneos) e não tivemos nenhum problema com ele - portanto, nunca veja essa mensagem de aviso.
fonte
isClosed()
testes, porque fechar um desses que já está fechado é um não-op. O que elimina o problema da janela de temporização. O que também seria eliminado criando as variáveis localConnection, Statement
eResultSet
.