L'eccezione indica un caso tipico di codice dell'applicazione che perde le connessioni al database. Devi assicurarti di acquisire e chiudili tutti (Connection
, Statement
e ResultSet
) in un try-with-resources
blocco nello stesso metodo blocco secondo il normale idioma JDBC.
public void create(Entity entity) throws SQLException {
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(SQL_CREATE);
) {
statement.setSomeObject(1, entity.getSomeProperty());
// ...
statement.executeUpdate();
}
}
O quando non sei su Java 7, in un try-finally
bloccare. Chiudendoli in finally
garantirà la loro chiusura anche in caso di eccezioni.
public void create(Entity entity) throws SQLException {
Connection connection = null;
PreparedStatement statement = null;
try {
connection = dataSource.getConnection();
statement = connection.prepareStatement(SQL_CREATE);
statement.setSomeObject(1, entity.getSomeProperty());
// ...
statement.executeUpdate();
} finally {
if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
}
Sì, è comunque necessario chiudere le connessioni da soli, anche quando si utilizza il pool di connessioni. È un errore comune tra gli antipasti che pensano che poi gestirà automaticamente la chiusura. Questo non è vero . Il pool di connessioni in particolare restituisce una connessione avvolta che fa qualcosa di simile alla seguente in close():
public void close() throws SQLException {
if (this.connection is still eligible for reuse) {
do not close this.connection, but just return it to pool for reuse;
} else {
actually invoke this.connection.close();
}
}
Non chiuderli causerebbe il mancato rilascio della connessione al pool per il riutilizzo e quindi ne acquisirà una nuova ancora e ancora fino a quando il DB esaurirà le connessioni, causando l'arresto anomalo dell'applicazione.
Vedi anche:
- Con quale frequenza devono essere chiusi Connection, Statement e ResultSet in JDBC?
- È sicuro utilizzare un'istanza java.sql.Connection statica in un sistema multithread?
- Chiusura delle connessioni JDBC nel pool