【问题标题】:Using transactionally in Slick 3在 Slick 3 中以事务方式使用
【发布时间】:2016-05-19 00:51:22
【问题描述】:

通常您会在一个事务中运行两个或多个语句。但在我能找到的在 Slick 3 中使用 transactionally 的所有示例中,当我通常在循环中使用 for 时,有一个 for comprehension 可以对这些语句进行分组。

这可行(从事务中的两个表中删除):

   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 吗?有没有另一种方法可以在一个事务中运行两个或多个语句?

【问题讨论】:

    标签: scala slick slick-3.0


    【解决方案1】:

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

    val firstAction = table1.filter(_.id === id1).delete
    val secondAction = table2.filter(_.id === id2).delete
    
    val combinedAction = DBIO.seq(
      firstAction,
      secondAction
    ).transactionally
    

    【讨论】:

      【解决方案2】:

      对于您的情况,for/yield 并不是获得所需内容的唯一方法。但是您必须将其替换为等效表示。 对于 flatMaps 和 map 的组合,for 理解是 syntactic sugar。我们需要使用它们,因为我们使用一元组合来聚合 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 推导式,因为它更简洁、更易于理解且非常易于扩展。

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

      • 这将是一个 for 理解:

        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/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)
        

      【讨论】:

      • 您的示例似乎不正确。每个map 调用实际上应该是flatMap 调用,否则map 中的最后一个动作不会被执行,它只会创建一个动作并丢弃它。
      猜你喜欢
      • 2023-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-15
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      相关资源
      最近更新 更多