例外は、データベース接続をリークするアプリケーションコードの典型的なケースを示しています。 とを確実に取得する必要があります それらをすべて閉じます(Connection
、Statement
および ResultSet
) try-with-resources
通常の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();
}
}
または、Java 7を使用していない場合は、try-finally
ブロック。 finally
でそれらを閉じます 例外が発生した場合にも、それらが閉じられることを保証します。
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) {}
}
}
はい、接続プールを使用している場合でも、自分で接続を閉じる必要があります。初心者の間では、それが自動的にクローズを処理すると考えるのはよくある間違いです。これは真実ではありません 。つまり、接続プールは、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();
}
}
それらを閉じないと、接続が再利用のためにプールに解放されないため、DBが接続を使い果たしてアプリケーションがクラッシュするまで、新しい接続が何度も取得されます。
関連項目:
- JDBCでConnection、Statement、ResultSetを閉じる頻度はどれくらいですか?
- マルチスレッドシステムで静的java.sql.Connectionインスタンスを使用しても安全ですか?
- プール内のJDBC接続を閉じる