Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring boot 插入两个集合而不阻塞_Spring Boot_Kotlin_Spring Data Mongodb_Spring Webflux - Fatal编程技术网

Spring boot 插入两个集合而不阻塞

Spring boot 插入两个集合而不阻塞,spring-boot,kotlin,spring-data-mongodb,spring-webflux,Spring Boot,Kotlin,Spring Data Mongodb,Spring Webflux,我目前正在学习使用SpringWebFlux的ProjectReactor 我创建了一个简单的服务,它将按顺序插入到两个集合中。首先,我的服务将插入列表集合,然后将插入详细信息集合。如果两个操作都成功,它将返回第一个操作的实例(插入列表集合),如果其中一个操作不成功,它将回滚之前该操作创建的任何更改 以下是我的片段: override fun insert(business: Business): Mono<Business> = businessRepository.sav

我目前正在学习使用SpringWebFlux的ProjectReactor

我创建了一个简单的服务,它将按顺序插入到两个集合中。首先,我的服务将插入列表集合,然后将插入详细信息集合。如果两个操作都成功,它将返回第一个操作的实例(插入列表集合),如果其中一个操作不成功,它将回滚之前该操作创建的任何更改

以下是我的片段:

    override fun insert(business: Business): Mono<Business> = businessRepository.save(business)
    .doOnSuccess { businezz ->
        val businessDetails = businezz.businessDetails
        businessDetails!!.idBusiness = businezz.id
        businessDetailsService.insert(businessDetails).doOnError {
            businessRepository.delete(businezz).subscribe()
        }.subscribe()
    }
override-fun-insert(business:business):Mono=businessRepository.save(business)
.doOnSuccess{businezz->
val businessDetails=businezz.businessDetails
businessDetails!!.idBusiness=businessez.id
businessDetailsService.insert(businessDetails.do错误{
businessRepository.delete(businezz.subscribe)()
}.subscribe()
}
我觉得这是一种创造单声道的肮脏方式。因为第二个操作是块操作。当然,我可以先做一个插入列表,然后插入详细信息,再获取列表。但是,这实际上会调用数据库3次,而不是像上面的代码那样调用2次

我有没有办法创建一个非阻塞操作,只调用数据库2次


谢谢。

我对Kotlin不熟悉,但使用Java,您可以像这样做:

Mono<Business> insert(Business business) {
    return businessRepository.save(business)
            .flatMap(businezz -> {
                BusinessDetails businessDetails = ...;
                return businessDetailsService.insert(businessDetails)
                        .onErrorResume(throwable -> businessRepository
                                .delete(businezz)
                                .then(Mono.empty()))
                        .then(Mono.just(businezz));
            });
}
Mono插入(业务){
返回businessRepository.save(业务)
.flatMap(businez->{
BusinessDetails BusinessDetails=。。。;
返回businessDetailsService.insert(businessDetails)
.OneErrorResume(一次性->业务存储库
.删除(业务zz)
.然后(Mono.empty())
然后(Mono.just)(businezz);;
});
}
KOTLIN回答,谢谢David:

override fun insert(business: Business): Mono<Business> {
    return businessRepository.save(business).flatMap { businezz ->
        val businessDetails = businezz.businessDetails
        businessDetailsService.insert(businessDetails!!).onErrorResume { 
            businessRepository.delete(businezz).then(Mono.empty())
        }.then(Mono.just(businezz))
    }        
}
override fun insert(业务:业务):Mono{
返回businessRepository.save(business).flatMap{businessnezz->
val businessDetails=businezz.businessDetails
businessDetailsService.insert(businessDetails!!).OneErrorResume{
businessRepository.delete(businezz).then(Mono.empty())
}.then(Mono.just(businezz))
}        
}

Hi David,我删除了Java标记,因为您的问题只使用Kotlin。谢谢@LppEdd,我想既然Kotlin只是Java的一个扩展,添加Java标记就可以了。下次,我会小心的。Thx@Alexander Pankin。你给我一个主意。最后一个问题,为什么使用平面图而不是地图?因为,我使用的是Mono not FluxIn反应堆
flatMap
不会将通量“平坦”到Mono。当需要将“next”值传递给其他异步发布服务器时,我们将其与Mono或Flux一起使用。在将“下一个”值传递给同步函数时,我们使用
map
。感谢您的解释!!