Slick中事务内合并DBAction如何获取独立执行结果
解决方案
要在单个事务中分别获取表A、表B的插入条数,你需要调整DBIO操作的组合方式,将表A的多插入操作合并为一个统计总条数的DBIO,再与表B的插入操作组合,最终在事务中执行并获取元组形式的结果。
具体实现步骤
- 合并表A的插入操作并统计总数:使用
DBIO.sequence执行表A的所有插入动作,随后通过map(_.sum)计算总插入条数(每个单条插入返回的是影响行数,求和后就是表A的总插入数)。 - 组合表A与表B的操作:将表A的统计DBIO和表B的单条插入DBIO组合为一个返回元组的DBIO,这样就能同时得到两个结果。
- 事务中执行:将组合后的DBIO用
transactionally包裹,确保所有操作在同一个事务内完成。
修正后的代码示例
val tableAInserts: Seq[ProfileAction[Int]] = Seq(insertAction1TableA, insertAction2TableA, insertAction3TableA, ...) val tableBInsert: ProfileAction[Int] = singleInsertProfileActionTableB // 计算表A的总插入条数 val tableATotal: DBIO[Int] = DBIO.sequence(tableAInserts).map(_.sum) // 组合两个操作,返回(表A总条数, 表B条数)的元组 val combinedAction: DBIO[(Int, Int)] = DBIO.tuple(tableATotal, tableBInsert) // 或者用for推导式,逻辑更清晰: // val combinedAction: DBIO[(Int, Int)] = for { // aCount <- DBIO.sequence(tableAInserts).map(_.sum) // bCount <- tableBInsert // } yield (aCount, bCount) // 在事务中执行,获取结果 val result: Future[(Int, Int)] = db.run(combinedAction.transactionally)
原代码的问题说明
你原代码中的Seq(tableAInserts) ++ tableBInsert存在类型错误:tableAInserts是Seq[ProfileAction],因此Seq(tableAInserts)会生成Seq[Seq[ProfileAction]],与单个tableBInsert拼接后类型不兼容。即使强行编译通过,DBIO.sequence执行后得到的是Seq[Seq[Int]],也无法直接区分表A和表B的插入结果。
内容的提问来源于stack exchange,提问作者Guillermo Coscarelli
相关产品推荐
相关产品推荐

