简体   繁体   English

根据请求分配连接池

[英]Slick Connection Pool on per requests

How can use slick connection pool ? 如何使用光滑的连接池?
For example : 例如 :
with this config : 使用此配置:

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
}

I have only one client and this client with web browser request to get all persons from API . 我只有一个客户端,并且此客户端带有Web浏览器,要求从API中获取所有人。
now slick generate 10 connection to database . 现在光滑生成到数据库的10个连接。
second step client refresh browser and slick generate new 10 connection to database without using previous connections . 第二步,客户端刷新浏览器并滑动生成新的数据库10连接,而无需使用以前的连接。
and then new refresh in browser and slick generate another 10 connection to database . 然后在浏览器中进行新的刷新并生成另一个与数据库的10连接。 (Now I have about 30 connection on DB with only one client!) (现在我只有一个客户端就可以在数据库上建立约30个连接!)

Why ? 为什么呢 This is normal ? 这很正常 ?
Why maxConnections not work ? 为什么maxConnections不起作用?
I must close connection after requests ? 请求后我必须关闭连接吗?
Or forget some configuration about that ? 还是忘记了一些配置?

Update 更新资料
This is my sample API : 这是我的示例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
}     

This is my example entity class (DAO Pattern) : 这是我的示例实体类(DAO模式):

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

}

This DatabaseConfig interface : 此DatabaseConfig接口:

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

  import driver.api._

  def db = Database.forConfig("database")

}

Note : I don't use play framework . 注意 :我不使用play框架。

Your configuration seems to be fine. 您的配置似乎很好。 It's impossible to say without further code samples from your application but my bet is you are creating your db on each and every request to your application. 如果没有来自应用程序的进一步代码示例,这是很难说的,但是我敢打赌,您是在对应用程序的每个请求上创建数据库的。

Just make sure that this code: 只要确保此代码:

Database.forConfig("database")

is executed once perhaps by: 通过以下方式执行一次:

  • putting it as a Singleton injected dependency or 将其作为Singleton注入依赖项或

  • by using play-slick and it's way of dealing with Slick configuration (if you are using Play which is, again, not possible to say from your question, though I assumed it as you mentioned web requests). 通过使用play-slick及其处理Slick配置的方式(如果您使用的是Play ,即使您提到了Web请求,我也无法从您的问题中说出这一点)。

EDIT (after question update): And we have an answer. 编辑(问题更新后):我们有一个答案。 Each time you call db method new Database object (together with connection pool is created). 每次调用db方法时,都会创建新的Database对象(连同连接池一起创建)。 Just move it as I suggested above (created once per application lifecycle). 就像我上面建议的那样移动它(每个应用程序生命周期创建一次)。 The easiest way possible (not necessarily the best one) would be to change this line: 最简单的方法(不一定是最好的方法)是更改此行:

def db = Database.forConfig("database")

to this: 对此:

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

Above would immediately solve your problem (assuming that there is only one instance of PersonsApi created in your application. 上面的方法可以立即解决您的问题(假设您的应用程序中PersonsApi创建了一个PersonsApi实例。

Other solution (better perhaps) would be to create something like this: 其他解决方案(也许更好)将是创建如下所示的内容:

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

  import driver.api._

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

and then change your API to this: 然后将您的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
} 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM