Slick and bonecp:org.postgresql.util.PSQLException:FATAL:抱歉,已经有太多客户端出错

Slick and bonecp:org.postgresql.util.PSQLException:FATAL:抱歉,已经有太多客户端出错,postgresql,scala,playframework,slick,bonecp,Postgresql,Scala,Playframework,Slick,Bonecp,在本地开发应用程序时,我使用sbt run 我喜欢修改代码,然后重新加载浏览器以查看修改 在大约10次代码更改之后,我得到了一个postgresql过多连接错误(见下文) 我的db连接使用下面的DatabaseAccess.scala类 我猜每次重新加载都会创建一组到postgresql的连接。在我的全球计划中,我目前正在做: override def onStart(app: Application) { Logger.info("Global.onStart") Datab

在本地开发应用程序时,我使用
sbt run

我喜欢修改代码,然后重新加载浏览器以查看修改

在大约10次代码更改之后,我得到了一个postgresql过多连接错误(见下文)

我的db连接使用下面的DatabaseAccess.scala类

我猜每次重新加载都会创建一组到postgresql的连接。在我的全球计划中,我目前正在做:

override def onStart(app: Application) {
    Logger.info("Global.onStart")

    DatabaseAccess.loadConfiguration()
  }
在生产中,我还担心如果我在短时间内进行多次部署,或者启动/停止我的服务,我可能也会遇到这个问题

如何确保所有连接都被破坏?我知道我可以在onStart或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)

Slick
自动处理会话关闭。从文件中:

数据库对象的withSession方法创建一个会话,将其传递给给定函数,然后将其关闭。如果使用连接池,关闭会话将返回到该池的连接


问题是
Bonecp
dataSource
连接未关闭,如图所示,您需要使用
dataSource.close()

手动关闭连接。我找到了要点,也许它能帮到您。@EndeNeu我更新了我的问题,说明了我是如何使用数据库的(我正在使用db.withSession{…})我从来没有使用过Bonecp,但我想光滑的
withSession
处理得很好,问题是Bonecp打开的
datSource
连接,查看您需要调用
dataSource.close()的要点
即使slick会话已过期。@EndeNeu感谢我这么做,如果有效,我会向您报告(这很有意义)。如果不是boncecp,你会用什么?Slick有自己的jdbc驱动程序类,对于Postgres,我使用
scala.Slick.driver.PostgresDriver.simple.
作为我的模型(例如CRUD操作),而打开会话(使用
DB.withSession
),我只使用
play.api.DB.Slick.
play.api.play.current
。实际上,我没有处理连接的类,在我的入口点中,我只是使用
DB.withSession
隐式地处理会话。
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