Domanda

Quite often I see code like that even in Java 7

    Connection c = null;
    PreparedStatement s = null;
    try {
        c = dataSource.getConnection();

        String sql = "insert into table (column1, column2) values (?, ?);
        s = c.prepareStatement(sql);
        int i = 1;
        s.setString(i++, "111");
        s.setString(i++, "222");

        s.execute();

    } catch (SQLException e) {
        log.error("failed to insert", e);
    } finally {
        DbUtils.close(s, c); // closes s and c with no questions
    }

But according to specification when the connection is closed all statements and result sets are freed.

I've heard there's a possibility to JDBC driver not to play by the rules of JDBC API, and the old way is better. My question was to hear opinions about that. The code looks better but what if it's dangerous? The most preferred way seems to me is to use try-with-resources here. Is it safe enough?

È stato utile?

Soluzione

A resource is an object that must be closed after the program is finished with it.So You don't have to close the Object manually in the finally block

 String sql = "insert into table (column1, column2) values (?, ?);
    try(Connection  c = dataSource.getConnection();
    PreparedStatement s = c.prepareStatement(sql);) {


        int i = 1;
        s.setString(i++, "111");
        s.setString(i++, "222");

        s.execute();

    } catch (SQLException e) {
        log.error("Failed to insert transaction", e);
    } 

Altri suggerimenti

You should always free/close the resources you use like ResultSet, Statement, Connection. That should be done in finally block. The snippet you pasted here looks OK (as far as s and c are closed in QuietDb).

While closing a Connection will close all Statements associated with it, there's an upper limit in most databases on how many Statements you can have open concurrently for any one Connection.

If you don't close Statements, you increase the likelyhood of errors like ORA-01000: maximum open cursors exceeded.

If you close Statements, they also close their ResultSets, so you don't have to close both.

Using try-with-resources your code can be rewritten to:

try (
    Connection c = dataSource.getConnection();
    PreparedStatement s = c.prepareStatement("insert into table (column1, column2) values (?, ?)");
) {
    int i = 1;
    s.setString(i++, "111");
    s.setString(i++, "222");

    s.execute();
} catch (SQLException e) {
    log.error("failed to insert", e);
}

This guarantees that both the statement and the connection get closed (even when closing the statement throws an Exception!). The only difference might be that an exception on close might now get thrown as I don't know if your DbUtils.close swallows exceptions.

In general try-with-resources provides cleaner code, and more assurance that resource get closed correctly, in the right order, without too much boiler plate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top