Wyjątek wskazuje na typowy przypadek kodu aplikacji, który przecieka połączenia z bazą danych. Musisz upewnić się, że zdobędziesz i zamknij je wszystkie (Connection
, Statement
i ResultSet
) w try-with-resources
blok w tym samym bloku metody zgodnie z normalnym idiomem 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();
}
}
Lub gdy nie korzystasz z Javy 7, w try-finally
blok. Zamknięcie ich w finally
zagwarantuje, że zostaną one również zamknięte w przypadku wyjątków.
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) {}
}
}
Tak, nadal musisz samodzielnie zamykać połączenia, nawet podczas korzystania z puli połączeń. Jest to powszechny błąd wśród początkujących, którzy myślą, że wtedy automatycznie obsłuży zamknięcie. To nieprawda . Pula połączeń, a mianowicie zwraca opakowane połączenie, które wykonuje coś takiego w 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();
}
}
Niezamknięcie ich spowoduje, że połączenie nie zostanie zwolnione z powrotem do puli w celu ponownego użycia, a tym samym będzie uzyskiwać nowe, dopóki DB nie wyczerpie się połączeń, co spowoduje awarię aplikacji.
Zobacz też:
- Jak często połączenie, oświadczenie i zestaw wyników powinny być zamykane w JDBC?
- Czy używanie statycznej instancji java.sql.Connection w systemie wielowątkowym jest bezpieczne?
- Zamykanie połączeń JDBC w puli