【发布时间】:2014-07-26 18:08:46
【问题描述】:
当我在本地开发我的应用程序时,我使用sbt run启动我的 play2 应用程序
我喜欢如何更改代码,然后重新加载浏览器以查看我的更改。
在大约 10 次左右的代码更改后,我得到一个 postgresql 连接过多错误(见下文)。
我的数据库连接使用下面的 DatabaseAccess.scala 类。
我猜在每次重新加载时它都会创建一堆到 postgresql 的连接。在我的全球目前正在做:
override def onStart(app: Application) {
Logger.info("Global.onStart")
DatabaseAccess.loadConfiguration()
}
在生产中,我也担心如果我在短时间内进行多次部署,或者启动/停止我的服务,我也可能会遇到这个问题。
如何确保所有连接都被销毁?我知道我可以在 onStart 或 OnStop 中放一些东西,但我不确定如何清除以前可能存在的连接。 (假设这不是错误)
我确实创建了一个我在 onStop 上调用的 release() 方法,但这似乎不起作用:
def release() {
configs = Map[String, BoneCPConfig]()
dataSources = Map[String, BoneCPDataSource]()
databases = dataSources.map { case(key, value) => (key, Database.forDataSource(value)) }
}
我所做的只是重新初始化变量,所以我想这并不是我真正需要做的。
我的数据访问模式如下:
def getById(userId: Int): Option[User] = {
db.withSession { implicit session =>
return userDao.getById(userId)
}
}
我的数据库访问类如下所示:
我的 application.conf 连接如下所示:
#postgresql
db.default.driver="org.postgresql.Driver"
db.default.url = "jdbc:postgresql://localhost/testweb_development"
db.default.user = "testdbuser"
db.default.password = ""
db.default.minConnections = 4
db.default.maxConnections = 24
db.default.maxThreads = 2
在大约 10 次代码更改后进行本地开发并且 sbt 这样做很好,部分类重新加载我收到此错误:
play.api.Application$$anon$1: Execution exception[[SQLException: Unable to open a test connection to the given database. JDBC url = jdbc:postgresql://localhost/testweb_development, username = testdbuser. Terminating connection pool (set lazyInit to true if you expect to start your database after your app). Original Exception: ------
org.postgresql.util.PSQLException: FATAL: sorry, too many clients already
at org.postgresql.core.v3.ConnectionFactoryImpl.doAuthentication(ConnectionFactoryImpl.java:291)
at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:108)
at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:66)
at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:125)
at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:30)
at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:22)
at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:30)
at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24)
at org.postgresql.Driver.makeConnection(Driver.java:393)
at org.postgresql.Driver.connect(Driver.java:267)
at java.sql.DriverManager.getConnection(DriverManager.java:582)
at java.sql.DriverManager.getConnection(DriverManager.java:185)
at com.jolbox.bonecp.BoneCP.obtainRawInternalConnection(BoneCP.java:363)
at com.jolbox.bonecp.BoneCP.<init>(BoneCP.java:416)
at com.jolbox.bonecp.BoneCPDataSource.getConnection(BoneCPDataSource.java:120)
at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$4.createConnection(JdbcBackend.scala:47)
at scala.slick.jdbc.JdbcBackend$BaseSession.conn$lzycompute(JdbcBackend.scala:302)
at scala.slick.jdbc.JdbcBackend$BaseSession.conn(JdbcBackend.scala:302)
at scala.slick.jdbc.JdbcBackend$BaseSession.close(JdbcBackend.scala:316)
at scala.slick.backend.DatabaseComponent$DatabaseDef$class.withSession(DatabaseComponent.scala:31)
at scala.slick.jdbc.JdbcBackend$DatabaseFactoryDef$$anon$4.withSession(JdbcBackend.scala:46)
at com.exampleapp.services.UserServiceImpl.getById(UserService.scala:37)
at controllers.UsersController$$anonfun$show$1.apply(UsersController.scala:84)
at controllers.UsersController$$anonfun$show$1.apply(UsersController.scala:76)
at play.api.mvc.ActionBuilder$$anonfun$apply$10.apply(Action.scala:221)
at play.api.mvc.ActionBuilder$$anonfun$apply$10.apply(Action.scala:220)
at controllers.ActionWithContext$.invokeBlock(BaseController.scala:42)
at play.api.mvc.ActionBuilder$$anon$1.apply(Action.scala:309)
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:109)
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4$$anonfun$apply$5.apply(Action.scala:109)
at play.utils.Threads$.withContextClassLoader(Threads.scala:18)
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:108)
at play.api.mvc.Action$$anonfun$apply$1$$anonfun$apply$4.apply(Action.scala:107)
at scala.Option.map(Option.scala:145)
at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:107)
at play.api.mvc.Action$$anonfun$apply$1.apply(Action.scala:100)
at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:481)
at play.api.libs.iteratee.Iteratee$$anonfun$mapM$1.apply(Iteratee.scala:481)
at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:517)
at play.api.libs.iteratee.Iteratee$$anonfun$flatMapM$1.apply(Iteratee.scala:517)
at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$13.apply(Iteratee.scala:493)
at play.api.libs.iteratee.Iteratee$$anonfun$flatMap$1$$anonfun$apply$13.apply(Iteratee.scala:493)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
at akka.dispatch.TaskInvocation.run(AbstractDispatcher.scala:42)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
环境
I am running scala 2.10.3, play 2.2.3
I am launching my app using sbt run.
Postgresql driver version: 9.1-901.jdbc4
slick version: 2.0.1
bonecp version: 0.8.0.RELEASE
【问题讨论】:
-
我找到了this gist,也许对你有帮助。
-
@EndeNeu 我已经用我如何使用数据库(我正在使用 db.withSession {...})更新了我的问题,但感谢这一点,因为它让事情变得更清晰。
-
我从不使用 Bonecp,但我猜光滑的
withSession处理正确,问题是 Bonecp 打开的datSource连接,看看你需要调用dataSource.close()的要点,即使光滑的会话已过期。 -
@EndeNeu 谢谢我这样做了,如果可行,我会报告(这是有道理的)。所以如果不是 boncecp 你用什么?
-
Slick 有他自己的 jdbc 驱动程序类,对于 Postgres 我使用
scala.slick.driver.PostgresDriver.simple._用于我的模型(例如 CRUD 操作)而打开会话(使用DB.withSession)我只使用play.api.db.slick._和 @ 987654336@。我实际上没有处理连接的类,在我的入口点我只是使用DB.withSession并隐式传递会话。
标签: postgresql scala playframework slick bonecp