我遇到了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}
}
}
然后有/ list动作,使用显式会话简单调用UserService:
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次后会出现问题。
显然我在光滑的会话处理中做错了 - 在playframework中是否有任何关于光滑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
我会感谢任何正确方向的暗示。
答案 0 :(得分: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
然后永远不会得到错误(等待免费可用连接超时)。(我的应用程序部署在带有postgres数据库的heroku上)
答案 1 :(得分:0)
问题出在BaseController
特征的隐式会话定义中。似乎会话定义需要在Action级别而不是在控制器级别 - 不幸的是我无法解释原因(尚未)。
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
所以仍然缺少的是将经过身份验证的操作与播放版本的DBAction
混合。这里提出了同样的问题:compose slick dbaction with authenticated action
也许这个光滑/光滑的团队中的某个人可以介入并回答这些问题?