在 Slick 3 中以事务方式使用
Using transactionally in Slick 3
通常您会 运行 一个事务中的两个或多个语句。但是在我能找到的所有关于在 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
是必需的吗?是否有替代方法 运行 交易中的两个或多个语句?
对于您的情况,for/yield
并不是获得所需内容的唯一途径。但是你必须用它来代替等效的表示。
对于 flatMap
和 map
的组合,for comprehension 是 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 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)
您可以在每个 DBIOAction
上使用 transactionally
,而不仅仅是那些 for 理解的结果。例如,您可以将 transactionally
与 DBIO.seq
方法结合使用,该方法采用一系列操作并按顺序运行它们:
val firstAction = table1.filter(_.id === id1).delete
val secondAction = table2.filter(_.id === id2).delete
val combinedAction = DBIO.seq(
firstAction,
secondAction
).transactionally
通常您会 运行 一个事务中的两个或多个语句。但是在我能找到的所有关于在 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
是必需的吗?是否有替代方法 运行 交易中的两个或多个语句?
对于您的情况,for/yield
并不是获得所需内容的唯一途径。但是你必须用它来代替等效的表示。
对于 flatMap
和 map
的组合,for comprehension 是 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 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)
您可以在每个 DBIOAction
上使用 transactionally
,而不仅仅是那些 for 理解的结果。例如,您可以将 transactionally
与 DBIO.seq
方法结合使用,该方法采用一系列操作并按顺序运行它们:
val firstAction = table1.filter(_.id === id1).delete
val secondAction = table2.filter(_.id === id2).delete
val combinedAction = DBIO.seq(
firstAction,
secondAction
).transactionally