每个请求的光滑连接池

时间:2016-12-20 10:52:31

标签: scala slick

如何使用光滑的连接池?
例如:
使用此配置:

database {
  dataSourceClass = org.postgresql.ds.PGSimpleDataSource
  driver = org.postgresql.Driver
  properties = {
    url = "jdbc:postgresql://172.17.0.2/sampleDB"
    user = "user"
    password = "userpass"
  }
  minConnections = 10
  maxConnections = 20
  numThreads = 10
}

我只有一个客户端,这个带有Web浏览器请求的客户端可以从API中获取所有人员 现在光滑生成10个与数据库的连接 第二步客户端刷新浏览器和光滑生成新的10连接到数据库而不使用以前的连接 然后在浏览器和光滑的新刷新生成另一个10连接到数据库。 (现在我只有一个客户端在DB上有大约30个连接!)

为什么?这是正常的吗? 为什么maxConnections不起作用?
我必须在请求后关闭连接吗? 或者忘记一些配置?

更新
这是我的示例API:

trait PersonsApi extends DatabaseConfig with JsonMapper {

  val getAllPersons = (path("persons") & get) {
    complete(db.run(PersonDao.findAll))
  }

  val getPersonById = (path("persons" / IntNumber) & get) {
    num => complete(db.run(PersonDao.findById(num)))
  }


  val personsApi =
    getAllPersons ~ 
    getPersonById
}     

这是我的示例实体类(DAO Pattern):

class PersonTable(tag: Tag) extends Table[Person](tag, "persons") {
  def id = column[Long]("id", O.AutoInc, O.PrimaryKey)

  def name = column[String]("name")

  def family = column[String]("family")

  override def * : ProvenShape[Person] = (id.?, name, family) <> (Person.tupled, Person.unapply)
}


object PersonDao extends BaseDao {
  def findAll = personTable.result

  def findById(id: Long) = personTable.filter(_.id === id).result

}

此DatabaseConfig界面:

trait DatabaseConfig extends Config {
  val driver = slick.driver.PostgresDriver

  import driver.api._

  def db = Database.forConfig("database")

}

注意:我不使用Play框架。

1 个答案:

答案 0 :(得分:1)

您的配置似乎没问题。如果没有来自您的应用程序的更多代码示例,我们无法说出来,但我敢打赌,您正在为应用程序的每个请求创建数据库。

请确保此代码:

Database.forConfig("database")

可能会执行一次:

  • 将其作为Singleton注入的依赖项或

  • 使用play-slick及其处理Slick配置的方式(如果您使用的是Play,这又是不可能从您的问题,虽然我在你提到网络请求时假设了它。

编辑(问题更新后): 我们有一个答案。每次调用db方法时,都会创建新的Database对象(与连接池一起创建)。只需按照我上面的建议移动它(每个应用程序生命周期创建一次)。最简单的方法(不一定是最好的方法)就是改变这一行:

def db = Database.forConfig("database")

到此:

lazy val db = Database.forConfig("database")

上面会立即解决您的问题(假设您的应用程序中只创建了PersonsApi个实例。

其他解决方案(或许更好)就是创建这样的东西:

object DatabaseConfig extends Config {
  val driver = slick.driver.PostgresDriver

  import driver.api._

  lazy val db = Database.forConfig("database")
}

然后将您的API更改为:

trait PersonsApi extends JsonMapper {

  val getAllPersons = (path("persons") & get) {
    complete(DatabaseConfig.db.run(PersonDao.findAll))
  }

  val getPersonById = (path("persons" / IntNumber) & get) {
    num => complete(DatabaseConfig.db.run(PersonDao.findById(num)))
  }


  val personsApi =
    getAllPersons ~ 
    getPersonById
}