【问题标题】:Sharing database session between multiple methods in Slick 3在 Slick 3 中的多个方法之间共享数据库会话
【发布时间】:2015-08-02 23:40:03
【问题描述】:

我最近从 Slick-2 切换到 Slick-3。 slick-3 一切运行良好。但是,在交易方面我遇到了一些问题。 我见过不同的问题和示例代码,其中transactionallywithPinnedSession 用于处理事务。但我的情况略有不同。可以在Query 上应用transcationally 和withPinnedSession。但我想要做的是将同一个会话传递给另一个方法,该方法将执行一些操作并希望将多个方法包装在同一个事务中。

我有下面的 slick-2 代码,我不确定如何使用 Slick-3 来实现。

def insertWithTransaction(row: TTable#TableElementType)(implicit session: Session) = {
      val entity = (query returning query.map(obj => obj) += row).asInstanceOf[TEntity]
      // do some operations after insert
      //eg: invoke another method for sending the notification
      entity
}

override def insert(row: TTable#TableElementType) = {
    db.withSession {
      implicit session => {
        insertWithTransaction(row)
      }
    }
}

现在,如果有人对交易不感兴趣,他们可以调用insert() 方法。 如果我们需要做一些交易,可以在db.withTransaction块中使用insertWithTransaction()来完成。

例如:

db.withTransaction { implicit session =>
    insertWithTransaction(row1)
    insertWithTransaction(row2)
    //check some condition, invoke session.rollback if something goes wrong
}

但是使用 slick-3,事务性只能应用于查询。 这意味着,只要我们需要在插入后集中执行一些逻辑,这都是可能的。每个开发人员都需要明确地手动处理这些场景,如果他们正在使用事务。我相信这可能会导致错误。我试图抽象插入操作中的整个逻辑,以便实现者只需要担心事务成功/失败

在 slick-3 中有没有其他方法,我可以将同一个会话传递给多个方法,以便一切都可以在单个 db 会话中完成。

【问题讨论】:

    标签: scala transactions slick


    【解决方案1】:

    您缺少一些东西:.transactionally 不适用于 Query,但适用于 DBIOAction。 然后,一个DBIOAction 可以通过使用一元组合来组合多个查询。

    这是来自文档的示例:

    val action = (for {
      ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result
      _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*)
    } yield ()).transactionally
    

    action 由一个select 查询和与第一个查询返回的行一样多的delete 查询组成。所有创建DBIOAction 并在事务中执行。

    然后,要对数据库运行操作,您必须调用db.run,所以,像这样:

    val f: Future[Unit] = db.run(action)
    

    现在,回到您的示例,假设您想在插入后应用 update 查询,您可以通过这种方式创建操作

    val action = (for {
      entity <- (query returning query.map(obj => obj) += row)
      _ <- query.map(_.foo).update(newFoo)
    } yield entity).transactionally
    

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 2017-04-08
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2011-06-16
      • 2010-12-01
      • 1970-01-01
      • 2019-12-07
      • 1970-01-01
      相关资源
      最近更新 更多