1

我在使用 Slick 2.0.1 和 play-slick 0.6.0.1 进行会话和连接处理时遇到问题

错误是

[SQLException: Timed out waiting for a free available connection.]
[...]
Caused by: java.sql.SQLException: Timed out waiting for a free available connection.
    at com.jolbox.bonecp.DefaultConnectionStrategy.getConnectionInternal(DefaultConnectionStrategy.java:88) ~[bonecp.jar:na]
[...]

我有一个游戏基础控制器特性,用于在一个地方设置显式会话

trait BaseController extends Controller with Secured {
    import play.api.Play.current
    implicit def session: SessionDef = play.api.db.slick.DB.withSession {
        implicit session => {session}
    }
}

然后是使用显式会话对 UserService 进行简单调用的 /list 操作:

object List extends BaseController with Secured {
  def index = IsAuthenticated { username =>
    implicit request =>
    UserService.findByEmail(username).map { user =>
      Ok(views.html.List.index(user))
    }.getOrElse(Forbidden)
  }
}

我已经删除了所有异步操作,所以我认为这个问题不会与类似问题重复:Play slick and Async - 这是一个竞争条件吗?Scala Play 2.2 Slick 1.0.1 - future { Try {...} } 等待免费可用连接时超时

重新加载操作大约 10 次后会出现此问题。

显然,我在 slick 的会话处理中做错了 - 在 playframework 中有没有 slick 2 会话处理的好例子?什么是最好的做法?

编辑:问题的一个可能来源可能是我用来保存 TableQueries 的对象

object Models {
    val users = TableQuery[Users]
    val mailinglists = TableQuery[Mailinglists]
    val mailinglistMemberships = TableQuery[MailinglistMemberships]
}

如果这可能是问题的根源,那么放置这些参考资料的好地方是什么?对象的主要原因是在表定义的外键中引用这些实例(类似于http://slick.typesafe.com/doc/2.0.1/schemas.html#constraints

编辑:这是 findByEmail 的代码 - 但我认为这并不重要。在所有查询中似乎都是相同的行为和问题。

def findByEmail(email: String)(implicit session: Session): Option[User]
  = Models.users.filter(_.email === email).firstOption

我会感谢任何指向正确方向的提示。

4

2 回答 2

0

问题出在BaseController特征中的隐式会话定义中。似乎会话定义需要在操作级别而不是控制器级别 - 不幸的是我无法解释原因(还)。

trait BaseController extends Controller with Secured {
    //REMOVED this code
    //import play.api.Play.current
    //implicit def session: SessionDef = play.api.db.slick.DB.withSession {
    //    implicit session => {session}
    //}
}

使用帮助更新了控制器操作DbAction- 不会导致连接超时。

trait Application extends Controller {
  def index = DBAction { implicit request =>
    request.session.get("email") flatMap (email => UserService.findByEmail(email)) map { user =>
      Ok(views.html.index(user))
    } getOrElse {
      Ok(views.html.index(null))
    }
  }
}

object Application extends Controller with Application

因此,仍然缺少将经过身份验证的操作与DBActionplay-slick 混合在一起。这里也提出了同样的问题:compose slick dbaction with authenticated action

也许 slick/play-slick 团队中的某个人可以介入并回答这些问题?

于 2014-04-05T12:39:32.757 回答
0

我也遇到了同样的问题。似乎应用程序没有从连接池中获得连接。所以我使用了配置:

db.default.partitionCount=1  
db.default.maxConnectionsPerPartition=20 
db.default.minConnectionsPerPartition=10 
db.default.acquireIncrement=1    
db.default.acquireRetryAttempts=5 
db.default.acquireRetryDelay=5 seconds 
db.default.acquireRetryDelay=5 seconds
db.default.idleMaxAge=10 minute 
db.default.idleConnectionTestPeriod=5 minutes 
db.default.initSQL="SELECT 1" 
db.default.maxConnectionAge=1 hour

然后永远不会出错(等待免费可用连接时超时)。(我的应用程序部署在 heroku 上,带有 postgres 数据库)

于 2014-03-25T16:15:32.710 回答