Scala Doobie & Hikari CP 事务处理器处理
Scala Doobie & Hikari CP transactor handling
如果这样做,HikariCP 每次都会初始化并关闭。
有没有办法避免这种情况并执行各种查询?
// Resource yielding a transactor configured with a bounded connect EC and an unbounded
// transaction EC. Everything will be closed and shut down cleanly after use.
val transactor: Resource[IO, HikariTransactor[IO]] =
for {
ce <- ExecutionContexts.fixedThreadPool[IO](32) // our connect EC
be <- Blocker[IO] // our blocking EC
xa <- HikariTransactor.newHikariTransactor[IO](
"org.h2.Driver", // driver classname
"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", // connect URL
"sa", // username
"", // password
ce, // await connection here
be // execute JDBC operations here
)
} yield xa
运行
transactor.use(sql"select 42".query[Int].unique.transact[IO]).unsafeRunSync()
这不是您在应用程序中使用 Resource
的方式。
您确实在 main
级别的某处执行了 .use
,然后让需要 Transactor
的整个代码都传递了该值,例如:
val actorSystemResource: Resource[IO, ActorSystem]
val transactorResource: Resource[IO, Transactor[IO]]
// initialize controllers, services, etc and create routes for them
def routes(actorSystem: ActorSystem, transactor: Transactor[IO]): Route
val resources = for {
transactor <- transactorResource
actorSystem, <- actorSystemResource
route = routes(actorSystem, transactor)
} yield (transactor, actorSystem, route)
resources.use { case (_, actorSystem, route) =>
implicit system = actorSystem
IO.fromFuture {
Http().bindAndHandle(route, "localhost", 8080)
}
}
或者,您可以使用 resource.allocated
,但这几乎肯定是一个坏主意,导致代码永远不会运行 Bracket
的发布部分,因为它很容易搞砸和例如如果抛出某些异常则不调用它。
如果这样做,HikariCP 每次都会初始化并关闭。 有没有办法避免这种情况并执行各种查询?
// Resource yielding a transactor configured with a bounded connect EC and an unbounded
// transaction EC. Everything will be closed and shut down cleanly after use.
val transactor: Resource[IO, HikariTransactor[IO]] =
for {
ce <- ExecutionContexts.fixedThreadPool[IO](32) // our connect EC
be <- Blocker[IO] // our blocking EC
xa <- HikariTransactor.newHikariTransactor[IO](
"org.h2.Driver", // driver classname
"jdbc:h2:mem:test;DB_CLOSE_DELAY=-1", // connect URL
"sa", // username
"", // password
ce, // await connection here
be // execute JDBC operations here
)
} yield xa
运行
transactor.use(sql"select 42".query[Int].unique.transact[IO]).unsafeRunSync()
这不是您在应用程序中使用 Resource
的方式。
您确实在 main
级别的某处执行了 .use
,然后让需要 Transactor
的整个代码都传递了该值,例如:
val actorSystemResource: Resource[IO, ActorSystem]
val transactorResource: Resource[IO, Transactor[IO]]
// initialize controllers, services, etc and create routes for them
def routes(actorSystem: ActorSystem, transactor: Transactor[IO]): Route
val resources = for {
transactor <- transactorResource
actorSystem, <- actorSystemResource
route = routes(actorSystem, transactor)
} yield (transactor, actorSystem, route)
resources.use { case (_, actorSystem, route) =>
implicit system = actorSystem
IO.fromFuture {
Http().bindAndHandle(route, "localhost", 8080)
}
}
或者,您可以使用 resource.allocated
,但这几乎肯定是一个坏主意,导致代码永远不会运行 Bracket
的发布部分,因为它很容易搞砸和例如如果抛出某些异常则不调用它。