Chiusura delle connessioni del database in Java

Sto diventando un po ‘confuso, stavo leggendo il seguito da http://en.wikipedia.org/wiki/Java_Database_Connectivity

Connection conn = DriverManager.getConnection( "jdbc:somejdbcvendor:other data needed by some jdbc vendor", "myLogin", "myPassword" ); Statement stmt = conn.createStatement(); try { stmt.executeUpdate( "INSERT INTO MyTable( name ) VALUES ( 'my name' ) " ); } finally { //It's important to close the statement when you are done with it stmt.close(); } 

Non hai bisogno di chiudere la connessione Conn? Cosa sta realmente succedendo se conn.close () non si verifica?

Ho un’applicazione web privata che sto mantenendo che al momento non chiude nessuna delle due forms, ma quella importante è davvero quella stmt, quella conn o entrambe?

Il sito continua a spegnersi a intermittenza, ma il server continua a dire che si tratta di un problema di connessione al database, il mio sospetto è che non venga chiuso, ma non so se chiuderlo.

    Quando hai terminato di utilizzare la tua Connection , devi chiuderla esplicitamente chiamando il suo metodo close() per rilasciare qualsiasi altra risorsa del database (cursori, handle, ecc.) Su cui la connessione può essere tenuta.

    In realtà, il modello sicuro in Java è quello di chiudere ResultSet , Statement e Connection (in questo ordine) in un blocco finally quando hai finito con loro, qualcosa del genere:

     Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; try { // Do stuff ... } catch (SQLException ex) { // Exception handling stuff ... } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { /* ignored */} } if (ps != null) { try { ps.close(); } catch (SQLException e) { /* ignored */} } if (conn != null) { try { conn.close(); } catch (SQLException e) { /* ignored */} } } 

    Il blocco finally può essere leggermente migliorato in (per evitare il controllo nullo):

     } finally { try { rs.close(); } catch (Exception e) { /* ignored */ } try { ps.close(); } catch (Exception e) { /* ignored */ } try { conn.close(); } catch (Exception e) { /* ignored */ } } 

    Ma, comunque, questo è estremamente prolisso, quindi in genere finisci per usare una class helper per chiudere gli oggetti in metodi helper nulli e il blocco finally diventa qualcosa del genere:

     } finally { DbUtils.closeQuietly(rs); DbUtils.closeQuietly(ps); DbUtils.closeQuietly(conn); } 

    E, in realtà, DbUtils di Apache Commons ha una class DbUtils che lo sta facendo esattamente così non c’è bisogno di scriverne uno proprio.

    È sempre meglio chiudere gli oggetti database / risorse dopo l’uso. Meglio chiudere la connessione, i risultati e gli oggetti istruzione nel blocco finally .

    Fino a Java7, tutte queste risorse devono essere chiuse utilizzando un blocco finally . Se stai utilizzando Java 7, per chiudere le risorse puoi procedere come segue.

     try(Connection con = getConnection(url, username, password, "org.postgresql.Driver"); Statement stmt = con.createStatement(); ResultSet rs = stmt.executeQuery(sql); ) { //statements }catch(....){} 

    Ora, gli oggetti con, stmt e rs diventano parte del blocco try e java chiude automaticamente queste risorse dopo l’uso.

    Spero di essere stato utile.

    È sufficiente chiudere solo Statement e Connection . Non è necessario chiudere esplicitamente l’object ResultSet .

    La documentazione Java dice su java.sql.ResultSet :

    Un object ResultSet viene automaticamente chiuso dall’object Statement che lo ha generato quando l’object Statement viene chiuso, rieseguito o utilizzato per recuperare il risultato successivo da una sequenza di più risultati.


    Grazie BalusC per i commenti: “Non mi fiderei di questo, alcuni driver JDBC falliscono.”

    Sì. Devi chiudere il set di risultati, la dichiarazione e la connessione. Se la connessione proviene da un pool, la sua chiusura lo invia di nuovo al pool per il riutilizzo.

    In genere devi farlo in un blocco finally{} , in modo tale che se viene lanciata un’eccezione, hai comunque la possibilità di chiuderla.

    Molti framework si prenderanno cura di questo problema di allocazione delle risorse / deallocazione. es. Spring’s JdbcTemplate . Apache DbUtils ha dei metodi per occuparsi della chiusura del set di risultati / dell’istruzione / connessione, sia essa nulla o meno (e cattura le eccezioni alla chiusura), il che può essere di aiuto.

    Sì, è necessario chiudere la connessione. In caso contrario, il client del database manterrà generalmente la connessione socket e altre risorse aperte.

    In realtà, è meglio se usi un blocco try-with-resources e Java chiuderà tutte le connessioni quando esci dal blocco try.

    Dovresti farlo con qualsiasi object che implementa AutoClosable.

     try (Connection connection = getDatabaseConnection(); Statement statement = connection.createStatement()) { String sqlToExecute = "SELECT * FROM persons"; try (ResultSet resultSet = statement.execute(sqlToExecute)) { if (resultSet.next()) { System.out.println(resultSet.getString("name"); } } } catch (SQLException e) { System.out.println("Failed to select persons."); } 

    La chiamata a getDatabaseConnection è appena fatta. Sostituirlo con una chiamata che ti ottiene una connessione JDBC SQL o una connessione da un pool.