在Slick 3中使用事务处理

时间:2016-05-19 00:51:23

标签: scala slick slick-3.0

通常,您将在事务中运行两个或更多语句。但是在我在Slick 3中使用transactionally时可以找到的所有示例中,当我通常在循环中使用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)

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

2 个答案:

答案 0 :(得分:5)

对于您的案例for/yield并不是获得所需内容的唯一途径。但是你必须用它代替等价的表示。 对于flatMapmap的组合,理解为syntactic sugar。我们需要使用它们,因为我们使用monadic组合来聚合BDIOAction中的所有操作。 所以你也可以把它写成:

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

通常使用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)
    
  • 这将是flatMap/map s:

    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)
    

答案 1 :(得分:5)

您可以在每个transactionally上使用DBIOAction,而不仅仅是因为理解而导致的transactionally。例如,您可以将DBIO.seqval firstAction = table1.filter(_.id === id1).delete val secondAction = table2.filter(_.id === id2).delete val combinedAction = DBIO.seq( firstAction, secondAction ).transactionally 方法结合使用,该方法采取一系列操作并按顺序运行:

Mammal