【问题标题】:Kotlin coroutines with Spring JPA blocking repositoryKotlin 协程与 Spring JPA 阻塞存储库
【发布时间】:2022-12-12 15:00:45
【问题描述】:

我正在尝试将 kotlin 协程与“旧式”Spring JPA 存储库一起使用。 我创建了一个新的协程范围并在“异步”中运行所有 JPA 调用。 我看到即使使用非反应性 JDBC,我也提高了吞吐量。

但我想知道,Spring JPA 存储库中可能存在一些协程包装器吗? 用反射和 Spring“魔法”创造的东西?

【问题讨论】:

    标签: spring kotlin jdbc spring-data-jpa kotlin-coroutines


    【解决方案1】:

    可以将 Kotlin 协程与 Spring JPA 存储库一起使用。 Spring Data 的 JPA 存储库旨在与阻塞调用一起使用,因此您可以使用'异步'建设者。

    这是您如何执行此操作的示例:

    class UserRepository(private val jpaRepository: UserJpaRepository) {
    
        suspend fun findById(id: Long): User? {
            return GlobalScope.async { jpaRepository.findById(id).orElse(null) }.await()
        }
    
        suspend fun save(user: User): User {
            return GlobalScope.async { jpaRepository.save(user) }.await()
        }
    
    }
    

    在这个例子中,我们有一个'用户资料库'包装一个的类'UserJpaRepository'并提供用于调用存储库方法的挂起函数。这些函数使用'异步'构建器在后台线程中运行存储库调用,然后'等待'结果。

    然后您可以使用'用户资料库'在你的协程代码中是这样的:

    val user = userRepository.findById(1L)
    userRepository.save(user)
    

    请务必注意,JPA 存储库方法仍将阻塞,因此如果您从在 UI 线程上运行的协程中调用它们,您可能仍会遇到阻塞和 UI 冻结的情况。为避免这种情况,您应该始终使用'异步'建设者,并使用'withContext'或另一个协程构建器为阻塞调用切换到不同的线程。

    总之,您可以通过简单地使用 Kotlin 协程和 Spring JPA 存储库

    【讨论】:

    • 以这种方式使用 GlobalScope 是错误的,但无论如何,如果我们正在等待结果,则没有理由在另一个范围内启动协程。使用 async+await 之间没有任何内容也是错误的。要切换上下文,请改用withContext
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-05-21
    • 1970-01-01
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多