0

我想在我的反应式 sql 客户端事务中使用 Kotlin 协程。为简单起见,我将使用此处io.vertx.mutiny.sqlclient.Pool#withTransaction 文档中提到的提供的辅助函数。由于传递的函数不是协程挂起函数,因此当我尝试编译如下代码时出现错误Suspension functions can be called only within coroutine body

val client : PgPool
... 

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

withTransaction 的函数头如下所示

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

我问自己是否还有一种方法可以将它与 kotlin 协程一起使用,因为我对它们很陌生。

感谢您的任何帮助 !

4

1 回答 1

1

我不熟悉 Mutiny 和 Quarkus,但似乎有一种方法可以从转换Deferred<T>Uni<T>in mutiny-kotlin,您似乎正在使用它。

因此,您可以创建自己的暂停版本,withTransaction如下所示:

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()
}

然后使用它:

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

但这引出了一个问题,如果最终您想使用 Kotlin 协程,为什么要使用 Vertx 的 Mutiny 变体?我认为默认情况下 Vertx 可以与 Java 期货一起使用,这些期货也与协程集成。

于 2021-12-07T15:40:12.833 回答