koji.lin
06/18/2025, 11:45 PMclass HogeService {
suspend fun getArticle(id: String){
newSuspendedTransaction {
val article = articleRepo.find(id)
// what ever other repo
viewCountRepo.increase(article.id)
}
// other suspend logic here, like fetching some info from remote
....
return article
}
}
suspend fun <T : Any> dbQuery(context: CoroutineContext?, statement: suspend () -> T?): T? =
TransactionManager.currentOrNull()?.withSuspendTrnsaction(context, statement)
?:newSuspendedTransaction(context, statement = statement)
class ArticleRepo {
suspend fun find(id:String) {
return dbQuery(Dispatchers.IO) {
//....
}
}
}
// Same patter as ArticleRepo
class ViewCountRepo...
So this should be open transaction at service layer and pass transaction to repo to run on other Dispatcher.
Is this usage correct? Especially I saw https://www.jetbrains.com/help/exposed/transactions.html#working-with-coroutines has phrase like below that maybe my example is wrong due to transaction may start from ktor's eventloop dispatcher then used in IO and IO may use different thread in Dispatchers.IO. Maybe this means two unrelated coroutines but ok for parent/child relationship?
> Please note that such code remains blocking (as it still uses JDBC) and you should not try to share a transaction between multiple threads as it may lead to undefined behavior.
So curious if it's correct or I should do in another way.koji.lin
06/20/2025, 1:50 PMcoroutineContext + Dispatchers.IO
? I think yes when checking source but not fully confident