2

我正在尝试将 JDBI 与 Play 1.2.5 一起使用,但我遇到了数据库连接不足的问题。我正在使用 H2 内存数据库(在 application.conf,db=mem 中)

我创建了类来获取使用 Play 的 DB.datasource 的 jdbi 实例,如下所示:

public class Database {      
    private static DataSource ds = DB.datasource;

    private static DBI getDatabase() {       
        return new DBI(ds);       
    }

    public static <T> T withDatabase(HandleCallback<T> hc) {
        return getDatabase().withHandle(hc);       
    }

    public static <T> T withTransaction(TransactionCallback<T> tc) {
        return getDatabase().inTransaction(tc);
    }
}

每次我进行数据库调用时,都会创建一个新的 DBI 实例,但它总是包装相同的静态 DataSource 对象(play.db.DB.datasource)

发生的事情是,过了一会儿我得到以下信息:

CallbackFailedException occured : org.skife.jdbi.v2.exceptions.UnableToObtainConnectionException: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.

我很困惑,因为 DBI.withHandle() 和 DBI.withTransaction() 的全部意义在于在回调方法完成时关闭连接并释放资源。

我也尝试getDatabase()每次都返回相同的 DBI 实例,但出现了同样的问题。

我究竟做错了什么?

4

2 回答 2

1

呃。原来我在一些没有使用 withHandle() 的旧代码中泄漏了连接。一旦我升级它,问题就停止了

于 2013-01-06T13:04:45.280 回答
0

来自官方文档

因为 Handle 持有一个打开的连接,所以必须注意确保每个句柄在完成后都关闭。未能关闭 Handles 最终会因打开的连接而使您的数据库不堪重负,或者耗尽您的连接池。

事实证明,只要提供了回调函数,您就不能保证在回调函数中关闭句柄。

于 2020-01-30T00:45:07.830 回答