简体   繁体   English

播放框架:关闭JDBC连接

[英]Play framework: closing JDBC connection

Does one need to manually close a DB connection (JDBC) in the Play! 是否需要在Play中手动关闭数据库连接(JDBC)! framework (2.3.0) after each request? 框架(2.3.0)后的每个请求?

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 此处的示例仅执行DB.getConnection(),而未说明关闭连接的方法: 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. 所以我假设对每个GET / POST请求执行一个DB.getConnection()是可以接受的,并且我不需要关闭任何东西。 What about the sql statement? sql语句呢?

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. 客户端上的垃圾收集器当然可以清理Connection对象,但这不会通知服务器连接已关闭。 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). StatementResultSet相同(服务器端的光标)。

A better solution is to use a JDBC connection pool to amortize the cost of creating connections and manage closing them when done. 更好的解决方案是使用JDBC连接池来分摊创建连接的成本,并在完成连接后管理关闭它们。

You should also close your SQL resources in a finally block, wrapped in individual try/catch blocks: 您还应该在finally块中关闭SQL资源,该块包含在单独的try / catch块中:

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. 换句话说,您有责任在代码中的某个位置调用它们的close()方法,以便可以将它们立即返回到池中。

Regarding the SQL Statement I guess you don't have to explicitly close it. 关于SQL语句,我想您不必显式关闭它。 In the Javadoc for Connection.close() they say: 在Javadoc中的Connection.close()中,他们说:

Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released. 立即释放此Connection对象的数据库和JDBC资源,而不是等待它们自动释放。

If I understand this correctly Connection.close() should also release the Statement resources... 如果我正确理解这一点,Connection.close()也应该释放Statement资源。

There is a more elegant way with Scala (tested with Play 2.6 ): Scala有一种更优雅的方式(已通过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. 但是,当然,您需要在打开的连接上的某个时刻调用close(),以将其返回到连接池。 Another way is to let Play manage closing the connection for you: 另一种方法是让Play管理为您关闭连接:

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

See the Documentation 请参阅文档

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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