在Slick 3中共享多个方法之间的数据库会话

Yad*_*nan 7 scala transactions slick

我最近从Slick-2切换到Slick-3.一切都与光滑-3一起工作得非常好.但是,在交易方面我遇到了一些问题.我已经看到了不同的问题和示例代码,其中transactionallywithPinnedSession用于处理事务.但我的情况略有不同.transcationally和withPinnedSession都可以应用Query.但我想要做的是将同一个会话传递给另一个方法,该方法将执行一些操作并希望在同一个事务中包装多个方法.

我有下面的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)
      }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

例如:

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

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

还有其他方法,在slick-3中,我可以将同一个会话传递给多个方法,以便一切都可以在单个数据库会话中完成.

n1r*_*1r3 1

您错过了一些东西:.transactionally不适用于 a Query,但适用于 a DBIOAction。然后,aDBIOAction可以通过使用单子组合来由多个查询组成。

这是来自文档的示例:

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

actionselect由一个查询和delete与第一个查询返回的行数相同的查询组成。所有创建的内容DBIOAction都在事务中执行。

然后,要对数据库运行操作,您必须调用db.run,因此,如下所示:

val f: Future[Unit] = db.run(action)
Run Code Online (Sandbox Code Playgroud)

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

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

希望能帮助到你。