2016-05-19 45 views
1

通常您會在事務中運行兩個或多個語句。但在所有可以在Slick 3中使用transactionally找到的例子中,我通常在循環中使用for來理解將這些語句分組。在Slick 3中以事務方式使用

這個工作(從兩個表中刪除一個事務):

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需要的?有沒有其他的方法可以在事務中運行兩個或多個語句?

回答

4

您可以在每DBIOAction上使用transactionally,而不僅僅是理解的結果。例如,您可以結合使用transactionallyDBIO.seq方法,該方法的操作序列,依次運行它們:

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

val combinedAction = DBIO.seq(
    firstAction, 
    secondAction 
).transactionally 
4

對於您的情況,for/yield不是獲得您需要的唯一方法。但是你將不得不用它代替等價的表示。 對於flatMap s和map的組合,理解爲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) 

的理解力通常是因爲使用的是更清潔,更容易理解,很容易擴展。

讓我們來看看在一個交易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) 
    
+0

你的例子似乎是不正確的。每個'map'調用實際上應該是'flatMap'調用,其他地圖上的最後一個動作不會被執行,它只會創建一個動作並放棄它。 –

相關問題