【问题标题】:Play slick session connection timeout播放流畅的会话连接超时
【发布时间】:2014-03-24 23:51:37
【问题描述】:

我在使用 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]
[...]

我有一个 play base 控制器特性,用于在一个地方设置显式会话

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 - is it a race condition?Scala Play 2.2 Slick 1.0.1 - future { Try {...} } Timed out waiting for a free available connection

在重新加载操作大约 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

如果您能提供任何正确方向的提示,我将不胜感激。

【问题讨论】:

  • UserService.findByEmail(username) 是如何实现的

标签: scala playframework play-slick slick-2.0


【解决方案1】:

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

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 数据库)

【讨论】:

    【解决方案2】:

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

    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
    

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

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

    【讨论】:

      猜你喜欢
      • 2012-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多