简体   繁体   中英

Play framework: closing JDBC connection

Does one need to manually close a DB connection (JDBC) in the Play! framework (2.3.0) after each request?

The example here just does a DB.getConnection() and doesn't say anything about closing the connection: http://www.playframework.com/documentation/2.3.x/JavaDatabase

So I'm assuming that doing a DB.getConnection() for each GET/POST request is acceptable and that I don't need to close anything. What about the sql statement?

conn = ds.getConnection();
stmt = conn.createStatement();
stmt.execute("SOME SQL QUERY");
stmt.close();

This might be a very bad assumption, depending on your database vendor.

Connections are scarce resources, with both client and database server components. The garbage collector on the client can certainly clean up the Connection object, but that doesn't inform the server that the connection is closed. You'll soon run out of connections on the server side, because they're a finite resource. Same for Statement and ResultSet (cursor on the server side).

A better solution is to use a JDBC connection pool to amortize the cost of creating connections and manage closing them when done.

You should also close your SQL resources in a finally block, wrapped in individual try/catch blocks:

public class DatabaseUtils {

    private DatabaseUtils() {}

    // Similar for Statement and ResultSet
    public static void close(Connection c) {
        try {
            if (c != null) {
                c.close();
            }
        } catch { Exception e) {
            log.error(e);
        }
    }
}

And in your code:

Connection c = null;
try {
    c = ds.getConnection();    
    // Do something with the connection
} finally {
    DatabaseUtils.close(c);  // same for Statement and ResultSet
}

If you read the docs carefully you see that they do answer your first question:

It is important to note that resulting Connections are not automatically disposed at the end of the request cycle. In other words, you are responsible for calling their close() method somewhere in your code so that they can be immediately returned to the pool.

Regarding the SQL Statement I guess you don't have to explicitly close it. In the Javadoc for Connection.close() they say:

Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released.

If I understand this correctly Connection.close() should also release the Statement resources...

There is a more elegant way with Scala (tested with Play 2.6 ):

But of course you need to call close() at some point on the opened connection to return it to the connection pool. Another way is to let Play manage closing the connection for you:

// access "default" database
db.withConnection { conn =>
  // do whatever you need with the connection
}

See the Documentation

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM