在 Play for Scala 中断开 Slick JNDI 连接

Disconnect from Slick JNDI connection in Play for Scala

Slick 定义here如何使用 JNDI 连接到数据库:

val db = Database.forName(jndiName: String)

我使用上面的方法连接到 Play for Scala 中的数据库,在 application.conf 中定义 JNDI 连接:

   def read (jndi: String, code: Int) = {
      val db = Database.forName(jndi)
      val records = TableQuery[TableDB]
      val action = records.filter(_.code === code).result
      val future = db.run(action.asTry)
      future.map{ 
        case Success(s) => 
          if (s.length>0)
            Some(s(0))
          else
            None
        case Failure(e) => throw new Exception ("Failure in read: " + e.getMessage)
      }
   }

问题是:如何断开与JNDI 资源的连接?只是 db.close() ?有没有办法在read方法结束时隐式关闭连接?

不清楚是什么让你怀疑它。如果您查看可以创建连接的 forName, you may see that it just asks JNDI context to get object by the name you provided and then treat it as javax.sql.DataSource 的来源。 DataSource 不是 Closeable 或类似的东西,因此您不必明确释放它。关闭 db.

就足够了

至于在 read 方法结束时关闭,这可能不是您真正想要的,因为您 return Future 可能仍未完成,因此可能需要连接开放。所以你可能需要的是 Future.onComplete

  def read(jndi: String, code: Int) = {
    val records = TableQuery[TableDB]
    val action = records.filter(_.code === code).result
    val db = Database.forName(jndi)
    val future = db.run(action.asTry)
    future.onComplete(_ => db.close()) // <-- added line
    future.map {
      case Success(s) =>
        if (s.length > 0)
          Some(s(0))
        else
          None
      case Failure(e) => throw new Exception("Failure in read: " + e.getMessage)
    }
  }

您始终可以在应用关闭时使用 play 的关闭挂钩关闭数据库连接(这通常是您想要的),是的 db.close 足以停止连接,您的端口将被释放这就是你应该关心的。我不太确定为什么您希望数据库在该方法之后立即关闭,但是有一个非常简单的解决方法,不会污染代码,您只需将数据库注入该方法即可:

def read(db : Database, code: Int) = {
    val records = TableQuery[TableDB]
    val action = records.filter(_.code === code).result
    val future = db.run(action.asTry)
    future.map {
      case Success(s) =>
        if (s.length > 0)
          Some(s(0))
        else
          None
      case Failure(e) => throw new Exception("Failure in read: " + e.getMessage)

  } 

一旦你得到你想要的结果,这个方法的调用者可以关闭相应的数据库。更安全,更容易改变 :) 另一方面,你总是可以使用@SergGr 的解决方案,它也有效 :)