Playframework 1.2.5 和 JDBI

Posted

技术标签:

【中文标题】Playframework 1.2.5 和 JDBI【英文标题】:Playframework 1.2.5 and JDBI 【发布时间】:2013-01-06 12:42:31 【问题描述】:

我正在尝试将 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实例,但同样的问题发生了。

我做错了什么?

【问题讨论】:

【参考方案1】:

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

【讨论】:

你升级了什么? 在意识到 withHandle() 存在之前我自己写的一些代码【参考方案2】:

来自官方documentation

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

事实证明,无论何时提供回调函数,您都不能保证在回调函数中关闭句柄。

【讨论】:

以上是关于Playframework 1.2.5 和 JDBI的主要内容,如果未能解决你的问题,请参考以下文章

Play Framework 1.2.5.1 和 1.2.6 版本之间的区别?

将 playframework 1.2.5 与现有数据库一起使用

playframework 模块和路由

Play framework 1.2.5 应用启动慢

playframework 1.x 是不是处理跨站点脚本 (xss)?

与 Play Framework 1.2.5 JPA 的多对多关系