Java 8响应式流水线中调用依赖方法的实现问题
解决响应式流水线中顺序依赖的数据库操作问题
你用Mono.zip失败是因为它的设计目标是并行合并多个独立的Mono结果,不会等待前一个操作完成再执行后一个,自然没法把方法1的主键传递给方法2。要实现“先执行方法1,再用其结果执行方法2”的顺序依赖逻辑,应该用flatMap操作符。
核心实现思路
flatMap的作用是接收前一个Mono的输出,以此为参数创建新的Mono并执行,严格保证操作的顺序性——只有前一个Mono成功完成,才会触发下一个操作。
代码示例
假设你的方法定义如下:
// 方法1:插入主表并返回主键 Mono<Long> insertMainTable(MainEntity mainEntity); // 方法2:用主表主键插入映射表 Mono<Void> insertMappingTable(Long mainPk, MappingEntity mappingEntity);
响应式流水线的正确写法:
// 从请求中获取主表和映射表的实体数据 MainEntity mainEntity = extractMainEntityFromRequest(request); MappingEntity mappingEntity = extractMappingEntityFromRequest(request); insertMainTable(mainEntity) // 用方法1返回的主键调用方法2 .flatMap(mainPk -> insertMappingTable(mainPk, mappingEntity)) .subscribe( // 两个操作都成功时的处理逻辑,比如返回201状态码 success -> response.setStatus(HttpStatus.CREATED.value()), // 任意一步失败时的异常处理 error -> handleDatabaseError(error, response) );
进阶:保留两个操作的结果
如果需要同时获取方法1的主键和方法2的执行结果,可以在flatMap内部结合Mono.zip:
insertMainTable(mainEntity) .flatMap(mainPk -> Mono.zip( Mono.just(mainPk), // 保留主键 insertMappingTable(mainPk, mappingEntity) // 执行映射表插入 ) ) .subscribe(resultTuple -> { Long mainPk = resultTuple.getT1(); Void mappingInsertResult = resultTuple.getT2(); // 基于两个结果做后续处理 log.info("主表主键{}对应的映射表插入完成", mainPk); });
异常处理提示
如果方法1执行失败,flatMap不会触发方法2;如果方法2失败,可以通过onErrorResume等操作符实现回滚或友好的错误响应:
insertMainTable(mainEntity) .flatMap(mainPk -> insertMappingTable(mainPk, mappingEntity) // 映射表插入失败时,尝试删除主表数据做回滚 .onErrorResume(error -> deleteMainTable(mainPk).then(Mono.error(error))) ) .subscribe(...);
内容的提问来源于stack exchange,提问作者Sujoy
相关产品推荐
相关产品推荐

