scala - 使用 Doobie 在单个事务中进行多个查询?
问题描述
假设我有两个案例类C1
,C2
每个类都继承自 trait T
。我有两个Query0
由这些案例类参数化的对象Query0[C1]
和Query0[C2]
. 目标是,当我执行这些查询时,我想获得一个List[T]
包含这两个查询结果的单个查询。现在我让它在单独的交易中工作得很好。
def executeQuery[A <: T](query: Query0[A]): List[A]=
transactor.use { xa => query.stream.compile.toList.transact(xa) }.unsafeRunSync
val query1: Query0[C1] = generateQuery1
val query2: Query0[C2] = generateQuery2
val results: List[T] = executeQuery(query1) ++ executeQuery(query2)
问题是我使用 BigQuery 作为数据库后端,并且事务有很多与之相关的开销。我希望在一个事务中执行这两个查询并让它返回一个 List[T] 对象。有没有办法做到这一点?
解决方案
如果您不关心这两个查询的顺序,我建议您将compile
每个查询ConnectionIO[List[A]]
独立成,使用mapN
(因为ConnectionIO[T]
有Apply
实例)将它们组合起来并transact
组合ConnectionIO[List[A]
在一个事务中:
import cats.effect.{Async, ContextShift, Resource}
import cats.syntax.apply._
import doobie.Query0
import doobie.implicits._
import doobie.util.transactor.Transactor
class SomeDAO[F[_]: Async: ContextShift, T] {
val transactor: Resource[F, Transactor[F]] = ???
def compile[A <: T](query: Query0[A]): doobie.ConnectionIO[List[A]] =
query.stream.compile.toList
def executeTwo[A <: T](query1: Query0[A], query2: Query0[A]): F[List[A]] =
transactor.use { xa =>
(compile(query1), compile(query2))
.mapN(_ ++ _)
.transact(xa)
}
}
推荐阅读
- vuejs2 - Jest 遇到了一个意外的令牌错误 typescript Vue 2
- odoo - 单击按钮时显示弹出消息:Odoo
- python - 在python中将值分组在一起
- kotlin - Kotlin 中有没有办法创建/初始化一个多维数组而不给它值
- image - Node-Red 上传的图像损坏
- python - quiver plot wrong 矢量图
- next.js - Next.js 缓存 getServerSideProps 或 getStaticPath
- r - 成对的阿多尼斯,不正确的 p 值
- kubernetes - SSL 握手失败:使用 kubernetes 和邮递员的 SubjectDN 签名者
- android - kernel_write 导致内核崩溃