scala - 在 Slick 3 中的多种方法之间共享数据库 session

标签 scala transactions slick

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

我有下面的 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()方法。
如果我们需要做一些交易,可以使用 insertWithTransaction() 来完成。在 db.withTransaction堵塞。

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

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

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

最佳答案

你错过了一些东西:.transactionally不适用于 Query , 但到 DBIOAction .
然后,一个 DBIOAction可以通过使用 monadic 组合由多个查询组成。

这是来自文档的示例:

val action = (for {
  ns <- coffees.filter(_.name.startsWith("ESPRESSO")).map(_.name).result
  _ <- DBIO.seq(ns.map(n => coffees.filter(_.name === n).delete): _*)
} yield ()).transactionally
actionselect 组成查询和多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

希望能帮助到你。

关于scala - 在 Slick 3 中的多种方法之间共享数据库 session ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30371450/

相关文章:

php - codeigniter transact 将数据添加到两个表中

sql - ROLLBACK TRANSACTION 请求没有对应的 BEGIN TRANSACTION

mysql - 在 Scala 中,当进行巧妙的 sortBy 时,如何让它进行区分大小写的排序

scala - 光滑表定义中的自定义映射列类型

scala - Play Framework 2 : test a request with a json string as body

java - Java/Scala 的 ZeroMQ 回调

.net - 我可以重复使用交易吗?如何?

Java 调用带有隐式参数的 Scala 案例类?

Scala Play 异常 : Placeholder not replaced

postgresql - 在 Slick 3.2.1 (Scala) 中使用过滤器的 where 子句中的 LIKE