Search code examples
kotlinkotlin-coroutinesvert.xquarkusmutiny

Kotlin Coroutine transaction in Reactive SQL Client (Quarkus/Vert.X)


I want to use Kotlin coroutines in my reactive sql client transactions. For simplicity, I was going to use the provided helper function io.vertx.mutiny.sqlclient.Pool#withTransaction mentioned in the docs here. Since the passed function is not a coroutine suspend function, I'm getting an error like Suspension functions can be called only within coroutine body when Im trying to compile a code like the following

val client : PgPool
... 

suspend fun someServiceFunction () {
    client.withTransaction { connection ->
        repository.save(connection, entity).awaitSuspending()   //This is not working
        ...
    }
}

The function header for the withTransaction looks like this

@CheckReturnValue
public <T> Uni<T> withTransaction(Function<SqlConnection, Uni<T>> function)

I'm asking myself if there is still a way to use this with kotlin coroutines, since I'm pretty new to them.

Thank you for any help !


Solution

  • I'm not familiar with Mutiny nor Quarkus, but it seems there is a way to convert from Deferred<T> to Uni<T> in mutiny-kotlin, which you seem to be using.

    You could therefore create your own suspending version of withTransaction like this:

    import io.vertx.mutiny.sqlclient.SqlConnection
    import io.vertx.mutiny.sqlclient.Pool
    
    @OptIn(ExperimentalCoroutinesApi::class)
    suspend fun <T> Pool.withTransaction(block: suspend (SqlConnection) -> T): T = coroutineScope {
        client.withTransaction { connection ->
            async { block(connection) }.asUni()
        }.awaitSuspending()
    }
    

    And then use it:

    suspend fun someServiceFunction() {
        client.withTransaction { connection ->
            repository.save(connection, entity).awaitSuspending()
            // potentially other suspending stuff here, without the need to combine()
        }
    }
    

    But that begs the question, why use the Mutiny variant of Vertx things, if in the end you want to use Kotlin coroutines? I think by default Vertx works with Java futures which are also integrated with coroutines.