Hi, I'm curious about how to handle coroutine and ...
# exposed
k
Hi, I'm curious about how to handle coroutine and transaction well. There are some examples like

https://www.youtube.com/watch?v=Y-iMbMro9tE

have some information, but for the case like we want to wrap few repository call in the same transaction, I still have question. I'm using ktor so wanna make service suspend, also still use jdbc with suspend not r2dbc in beta.
Copy code
class 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.
Also curious about the context pass to newSuspendedTransaction, looks like even we just want to switch Dispatcher, it use new context fully but not like withContext that oldCtx + newlyPassedContext. Is this intentional? And does it safe to pass like
coroutineContext + Dispatchers.IO
? I think yes when checking source but not fully confident