Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How often should Connection, Statement and ResultSet be closed in JDBC?

Tags:

java

jdbc

Do they need to be closed after each query and initialized at the beginning of each query?

like image 429
deltanovember Avatar asked Apr 09 '11 03:04

deltanovember


People also ask

Does ResultSet need to be closed?

You should explicitly close Statements , ResultSets , and Connections when you no longer need them, unless you declare them in a try -with-resources statement (available in JDK 7 and after).

Do we need to close connection in JDBC?

At the end of your JDBC program, it is required explicitly to close all the connections to the database to end each database session. However, if you forget, Java's garbage collector will close the connection when it cleans up stale objects.

Does closing connection close ResultSet?

Yes it does, Connection.

What is default JDBC connection timeout?

Timeout Settings The default is 60 seconds.


2 Answers

Always. You need to acquire and close them in the shortest possible scope to avoid resource leaking, transactional problems and exhausted connection pools. Not doing so would cause the DB to run out of resources sooner or later, resulting in exceptions like "Too many connections".

The normal JDBC idiom is the following, whereby all resources are opened and closed in the very same try-with-resources block:

public List<Entity> list() throws SQLException {
    List<Entity> entities = new ArrayList<Entity>();

    try (
        Connection connection = database.getConnection();
        PreparedStatement statement = connection.prepareStatement(SQL_LIST);
        ResultSet resultSet = statement.executeQuery();
    ) {
        while (resultSet.next()) {
            entities.add(map(resultSet));
        }
    }

    return entities;
}

Or when you're not on Java 7 yet:

public List<Entity> list() throws SQLException {
    List<Entity> entities = new ArrayList<Entity>();
    Connection connection = null;
    PreparedStatement statement = null;
    ResultSet resultSet = null;

    try {
        connection = database.getConnection();
        statement = connection.prepareStatement(SQL_LIST);
        resultSet = statement.executeQuery();

        while (resultSet.next()) {
            entities.add(map(resultSet));
        }
    } finally {
        if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
        if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }

    return entities;
}

Using PreparedStatement will give you the benefit of the DB caching of the statements (next to SQL injection prevention when used properly). Acquiring and closing the connection is the most expensive task, but there the connection pools are invented for. If you want to reuse the same statement to do bulk inserts/updates, then you can use batches.

See also:

  • When my app loses connection, how should I recover it?
  • Is it safe to use a static java.sql.Connection instance in a multithreaded system?
like image 198
BalusC Avatar answered Nov 14 '22 22:11

BalusC


Since you don't want the results of a previous query, you need to initialize the ResultSet, of course.

The statement can be kept, if needed again, and especially PreparedStatements should be kept - they can be precompiled on the first run by the database, which saves some seconds:

"SELECT foo FROM bar WHERE a = ?" 

if only the parameter changes, of course.

like image 22
user unknown Avatar answered Nov 14 '22 23:11

user unknown