在Slick 3中使用事务处理

ps0*_*604 2 scala slick slick-3.0

通常,您将在事务中运行两个或更多语句.但是在我transactionally在Slick 3中使用的所有示例中,当我通常for在循环中使用时,可以理解这些语句的分组.

这有效(从事务中的两个表中删除):

   val action = db.run((for {
      _ <- table1.filter(_.id1 === id).delete
      _ <- table2.filter(_.id2=== id).delete
    } yield ()).transactionally)
    val result = Await.result(action, Duration.Inf)
Run Code Online (Sandbox Code Playgroud)

for/yield需要吗?是否有另一种方法可以在事务中运行两个或多个语句?

Car*_*hez 5

对于你的情况for/yield并不是获得你需要的唯一方法.但是你必须用它代替等价的表示.对于s和a 的组合,理解是语法糖.我们需要使用它们,因为我们使用monadic组合来聚合a中的所有动作.所以你也可以把它写成:flatMapmapBDIOAction

val action = db.run(
  table1.filter(_.id1 === id).delete.map ( _ =>
    table2.filter(_.id2=== id).delete
  ).transactionally
)
val result = Await.result(action, Duration.Inf)
Run Code Online (Sandbox Code Playgroud)

通常使用for comprehension,因为它更干净,更容易理解并且非常容易扩展.

让我们看一下在事务中有4个语句的示例,看看它的外观:

  • 这将是一个理解:

    val action = db.run((for {
      _ <- table1.filter(_.id1 === id).delete
      _ <- table2.filter(_.id2=== id).delete
      _ <- table3.filter(_.id3=== id).delete
      _ <- table4.filter(_.id4=== id).delete
    } yield ()).transactionally)
    val result = Await.result(action, Duration.Inf)
    
    Run Code Online (Sandbox Code Playgroud)
  • 这将与flatMap/maps:

    val action = db.run(
      table1.filter(_.id1 === id).delete.flatMap ( _ =>
        table2.filter(_.id2 === id).delete.flatMap ( _ =>
          table3.filter(_.id3 === id).delete.map ( _ =>
            table4.filter(_.id4=== id).delete
          )
        )
      ).transactionally
    )
    val result = Await.result(action, Duration.Inf)
    
    Run Code Online (Sandbox Code Playgroud)

  • 你的例子似乎不正确。每个 `map` 调用实际上应该是 `flatMap` 调用,否则 map 中的最后一个 action 不会被执行,它只会创建一个 action 并丢弃它。 (2认同)

Paw*_*nko 5

你可以transactionally在每一个上使用DBIOAction,而不仅仅是因为理解的结果.例如,您可以transactionallyDBIO.seq方法结合使用,该方法采取一系列操作并按顺序运行它们:

val firstAction = table1.filter(_.id === id1).delete
val secondAction = table2.filter(_.id === id2).delete

val combinedAction = DBIO.seq(
  firstAction,
  secondAction
).transactionally
Run Code Online (Sandbox Code Playgroud)