【问题标题】:How to make use of a shared session for multiple database operation in slick?如何在 slick 中使用共享会话进行多个数据库操作?
【发布时间】:2014-03-06 08:09:20
【问题描述】:

我正在使用 slick,并且对 slick session 有疑问。我先举个例子 Order 类包含行项目,Order 可以获取行项目或删除行项目之一,Order 也可以自行定价。下面是伪代码:

类顺序{

  def getLineItems= database withSesison{
      //get Line Items from db repository   
  }

  def removeLineItem(itemId: String) = database withTransaction{
      implicit ss: Session =>
      //Remove item from db
      //Price the order
  }

  def priceOrder() = database withTransaction{
      implicit ss: Session =>
      //getLineItems
      //recalculate order price by each line item
  }
}

所以当我尝试删除一个订单项时,它会创建一个新的 Session 和交易,然后它会调用 priceOrder,它也会创建一个新的 Session 和交易,priceOrder 会调用 getLineItems,它会创建另一个新的会话。

从 slick 文档中,我知道每个会话都打开一个 jdbc 连接,因此在一次方法调用中它将创建 3 个数据库连接,这是对连接资源的浪费。有没有办法只使用一个连接来完成这个操作?

我知道 slick 有一个 threadLocalSession 将会话绑定到线程本地,但是从 https://groups.google.com/forum/#!topic/scalaquery/Sg42HDEK34Q 我看到我们应该避免使用 threadLocalSession。

请帮忙,谢谢。

【问题讨论】:

    标签: scala slick


    【解决方案1】:

    您可以使用柯里化来传递隐式会话,而不是为每个方法创建新的会话/事务。

    def create(user: User)(implicit session: Session) = {
      val id = Users.returning(Users.map(_.id)).insert(user)
      user.copy(id = Some(id))
    }
    

    然后,在控制器或某个地方,当您想要调用方法时,您会设置一个会话/事务,它将用于该块内的所有数据库工作。

    // Create the user.
    DB.withTransaction { implicit session: Session =>
      Users.create(user)
    }
    

    隐式会话是一些 Slick 示例的设置方式。 https://github.com/slick/slick-examples/blob/master/src/main/scala/com/typesafe/slick/examples/lifted/MultiDBCakeExample.scala

    【讨论】:

    • 谢谢罗伯,你是对的。但有时我不想把session围在外面,因为我可能会在UI层或其他地方调用getLineItems之类的方法,所以我需要在实体对象中设置session,方便用户使用。
    猜你喜欢
    • 2015-08-02
    • 1970-01-01
    • 2015-01-05
    • 1970-01-01
    • 2019-12-07
    • 2011-02-03
    • 2010-09-21
    • 2010-09-21
    • 1970-01-01
    相关资源
    最近更新 更多