插入两个集合而不阻塞

Posted

技术标签:

【中文标题】插入两个集合而不阻塞【英文标题】:Inserting Into Two Collections Without Blocking 【发布时间】:2019-07-31 06:03:38 【问题描述】:

我目前正在学习使用 Spring-WebFlux 的 Project Reactor。

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

这是我的sn-p:

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

我觉得这是一种创建 Mono 的肮脏方式。由于第二个操作是块操作。当然,我可以只做一个插入列表然后插入详细信息然后获取列表。但是,这实际上会调用数据库 3 次,而不是像我上面的代码那样调用 2 次。

有什么方法可以让我创建一个非阻塞操作并且只调用 DB 2 次?

谢谢。

【问题讨论】:

嗨,大卫,我删除了 Java 标记,因为您的问题仅使用 Kotlin。 谢谢@LppEdd,我想既然Kotlin只是Java的扩展,添加java标签就可以了。下次我会小心的。 【参考方案1】:

我不熟悉 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));
            );

科特林回答,谢谢大卫:

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

【讨论】:

谢谢@Alexander Pankin。你给我一个主意。最后一个问题,为什么使用 flatMap 而不是 map?因为,我确实使用 Mono 而不是 Flux 在反应器中flatMap 不会将 Flux“扁平化”为 Mono。当需要将“下一个”值传递给其他异步发布者时,我们将它与 Mono 或 Flux 一起使用。我们使用map,将“下一个”值传递给同步函数。 谢谢你的解释!!

以上是关于插入两个集合而不阻塞的主要内容,如果未能解决你的问题,请参考以下文章

比较两个集合的相等性,而不考虑其中项目的顺序

Java之集合(二十二)PriorityBlockingQueue

关于Java集合类库中的几种常用队列

进程间通信中的集合点?

如何在多个任务之后继续而不阻塞 UI 线程?

mongoose 在 express 中使用 _id 链接两个集合,并将 id 作为数字或字符串插入