Scala Play 2.5 与 Slick 3 和 Spec2

Scala Play 2.5 with Slick 3 and Spec2

我有一个使用 Slick 的播放应用程序,我想使用 Spec2 对其进行测试,但我一直收到错误 org.postgresql.util.PSQLException: FATAL: sorry, too many clients already。我尝试使用

关闭数据库连接
val mockApp = new GuiceApplicationBuilder()
val db = mockApp.injector.instanceOf[DBApi].database("default")

...

override def afterAll = {
  db.getConnection().close()
  db.shutdown()
}

但错误依然存在。 Slick 配置为

slick.dbs.default.driver="slick.driver.PostgresDriver$"
slick.dbs.default.db.driver="org.postgresql.Driver"
slick.dbs.default.db.url="jdbc:postgresql://db:5432/hygge_db"
slick.dbs.default.db.user="*****"
slick.dbs.default.db.password="*****"
DbApi 的

getConnection 要么从基础数据源的(JdbcDataSource 我假设)池中获取连接,要么创建一个新的连接。我看到您的配置中没有指定池,所以我认为它总是为您创建一个新池。因此,如果您没有在测试中关闭连接 - getConnection 将无济于事 - 它只会尝试创建一个新连接或从池中获取随机连接(如果启用了池)。

所以解决方案是配置连接池:

When using a connection pool (which is always recommended in production environments) the minimum size of the connection pool should also be set to at least the same size. The maximum size of the connection pool can be set much higher than in a blocking application. Any connections beyond the size of the thread pool will only be used when other connections are required to keep a database session open (e.g. while waiting for the result from an asynchronous computation in the middle of a transaction) but are not actively doing any work on the database.

因此您可以在配置中设置最大可用连接数:

connectionPool = 5

或者您可以共享相同的连接(您可能必须确保顺序):

object SharedConnectionForAllTests{ 
  val connection = db.getConnection()
  def close() = connection.close()
}

当然最好用 Spring/Guice 注入,这样你就可以方便地管理连接的生命周期。