A exceção indica um caso típico de código de aplicativo que vaza conexões de banco de dados. Você precisa garantir que você adquira e feche todos eles (
Connection
, Statement
e ResultSet
) em um try-with-resources
block no mesmo bloco de método de acordo com o idioma JDBC normal. 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();
}
}
Ou quando você não estiver no Java 7, em um
try-finally
quadra. Fechando-os em finally
garantirá que eles também sejam fechados em caso de exceções. 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) {}
}
}
Sim, você ainda precisa fechar as conexões, mesmo ao usar o pool de conexões. É um erro comum entre os iniciantes pensarem que ele irá lidar automaticamente com o fechamento. Isso não é verdade . O pool de conexões retorna uma conexão encapsulada que faz algo como o seguinte no 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();
}
}
Não fechá-los faria com que a conexão não fosse liberada de volta ao pool para reutilização e, portanto, adquiriria um novo repetidamente até que o banco de dados ficasse sem conexões, o que faria com que seu aplicativo travasse.
Veja também:
- Com que frequência Connection, Statement e ResultSet devem ser fechados no JDBC?
- É seguro usar uma instância java.sql.Connection estática em um sistema multithread?
- Fechando conexões JDBC no pool