使用 async(Dispatchers.Default) 启动的协程中的存储库方法调用不会提供与主线程中相同的值

问题描述 投票:0回答:1

为了演示我的问题,我有以下简化代码:

家庭服务:

@Service
class FamilyService(
    private val familyRepository: FamilyRepository
    private val childService: ChildService
) {
    @Transactional(rollbackOn = [Exception::class])
    fun createFamily(familyLastName: String, childrenNames: List<String>): Family = runBlocking {
        val family = createFamilyEntity(familyLastName)


        println("family (in main): ${familyRepository.findByIdOrNull(family.id) ?: "none"}")

        val children = childrenNames.map { name ->
            async(Dispatchers.Default) {
                childService.createChild(family.id, name)
            }
        }.awaitAll()

        family
    }

    private fun createFamilyEntity(familyLastName: String): Family {
        val family = Family(id = UUID.randomUUID(), familyLastName = familyLastName)

        return familyRepository.save(family)
    }
}

儿童服务:

@Service
class ChildService(
    private val childRepository: ChildRepository,
    private val familyRepository: FamilyRepository
) {
    fun createChild(familyId: UUID, name: String): Child {
        println("family (in child): ${familyRepository.findByIdOrNull(familyId) ?: "none"}")
        
        val child = Child(id = UUID.randomUUID(), familyId = familyId, name = name)

        return childRepository.save(child)
    }
}

FamilyController
调用
FamilyService.createFamily
时,它会在控制台中打印如下内容:

family (in main): Family(id=...,familyLastName=...,...)
family (in child): none
family (in child): none
family (in child): none

并且在调用

childService.createChild
时返回错误,表示违反了
child
表的外键约束,因为与提供的 family id 关联的行在
family
表中不存在。但是它存在于
println
中的
createFamily
中,不知道为什么在不同的协程中调用它时就不存在了。

具体来说,错误如下所示(但具有不同的上下文,而不是家庭和子实体):

2024-04-24 14:41:29.743 ERROR 14984 --- [atcher-worker-3] [v:] [cid:] [huid:] o.h.engine.jdbc.spi.SqlExceptionHelper   : ERROR: insert or update on table "data_table_record" violates foreign key constraint "data_table_record_table_id_fkey"
  Detail: Key (table_id)=(176dfee6-7525-4741-a466-1acb85861317) is not present in table "data_table".
spring-boot kotlin spring-data-jpa kotlin-coroutines
1个回答
0
投票

我怀疑您是否处于完整的协程 Spring 堆栈上,因为您的服务类中的方法没有挂起函数。 @Transactional 不应该与协程一起使用(请参阅https://stackoverflow.com/a/64142241/8129835)。根据 Spring 文档,您应该使用

TransactionalOperator
来处理协程中的事务。

© www.soinside.com 2019 - 2024. All rights reserved.