当第二个操作的数据依赖于第一个时,如何在管道中链接操作
How to chain the operation in a pipeline when data of second operation is dependent upon first
我有一个场景,其中一些数据库调用依赖于其他,因此我不知道如何链接所有这些操作。
场景:考虑 3 table 个。一个用于从 table(数据库调用 1)获取增量编号,然后在获取编号后,递增并保存它(数据库调用 2),然后使用它来将其存储在另一个 table(数据库调用3), 然后需要在先前操作的 table (DB call 4)
的子 table 中存储更多信息
我不知道如何将所有这些操作保存在一个管道中。因此,我做了嵌套操作。由于在所有数据库操作完成之前,API 已经返回值。因此,在最坏的情况下,如果第 4 次数据库调用操作失败,API 仍然返回了不应该发生的值。
谁能建议如何在一条链中完成这项任务?
如何将第一个数据库调用的操作传递给同一链中的其他操作?
public Mono<MasterResponse> createMasterDetails(MasterRequest request)
{
MasterResponse response = new MasterResponse();
// DB op 1
seriesRepo.findByItemType(request.getItemType())
.doOnSuccess( series -> {
if(series == null)
throw new RunTimeException("Series detail not found for itemType: " + request.getItemType());
// 2nd DB operation is within this method
String billNo = getBillNumberByType(series);
MasterDetails masterDetails = new MasterDetails();
// operation to copy request info to masterDetails
masterDetails.setBillNo(billNo);
// returning dto value set
response.setBillNo(billNo);
// DB op 3
masterDetailsRepo.save(masterDetails)
.doOnSuccess(masterData -> {
MasterAttribute masterAttribute = new MasterAttribute();
// operation to copy request info to masterAttribute
masterDetails.setMasterId(masterData.getId());
masterDetailsRepo.save(masterDetails)
.doOnSuccess(ardRes -> log.info("master details saved in DB."))
.subscribe();
}).subscribe();
}).doOnError(err ->{
log.error("Unable to fetch information from series :: {}", err.getMessage());
Mono.error(new RunTimeException("Unable to fetch information from series :: {}" + err.getMessage()));
}).block();
return Mono.just(response);
}
根据我的理解,你实际上可以让它更简洁,而且你不需要使用 block()。
这是您可以使用的示例代码
return seriesRepo
.findByItemType(request.getItemType())
.switchIfEmpty(Mono.error({YOUR EXCEPTION})))
.flatMap(series -> Mono.just( getBillNumberByType(series) ))
.flatMap(billNo -> {
MasterDetails masterDetails = new MasterDetails();
// operation to copy request info to masterDetails
masterDetails.setBillNo(billNo);
return Mono.just(masterDetails);
}).flatMap(masterDetailsRepo::save)
.flatMap( masterDetails -> {
MasterResponse response = new MasterResponse();
response.setBillNo(masterDetails.getBillNo())
return Mono.just(response);
})
我有一个场景,其中一些数据库调用依赖于其他,因此我不知道如何链接所有这些操作。 场景:考虑 3 table 个。一个用于从 table(数据库调用 1)获取增量编号,然后在获取编号后,递增并保存它(数据库调用 2),然后使用它来将其存储在另一个 table(数据库调用3), 然后需要在先前操作的 table (DB call 4)
的子 table 中存储更多信息我不知道如何将所有这些操作保存在一个管道中。因此,我做了嵌套操作。由于在所有数据库操作完成之前,API 已经返回值。因此,在最坏的情况下,如果第 4 次数据库调用操作失败,API 仍然返回了不应该发生的值。 谁能建议如何在一条链中完成这项任务? 如何将第一个数据库调用的操作传递给同一链中的其他操作?
public Mono<MasterResponse> createMasterDetails(MasterRequest request)
{
MasterResponse response = new MasterResponse();
// DB op 1
seriesRepo.findByItemType(request.getItemType())
.doOnSuccess( series -> {
if(series == null)
throw new RunTimeException("Series detail not found for itemType: " + request.getItemType());
// 2nd DB operation is within this method
String billNo = getBillNumberByType(series);
MasterDetails masterDetails = new MasterDetails();
// operation to copy request info to masterDetails
masterDetails.setBillNo(billNo);
// returning dto value set
response.setBillNo(billNo);
// DB op 3
masterDetailsRepo.save(masterDetails)
.doOnSuccess(masterData -> {
MasterAttribute masterAttribute = new MasterAttribute();
// operation to copy request info to masterAttribute
masterDetails.setMasterId(masterData.getId());
masterDetailsRepo.save(masterDetails)
.doOnSuccess(ardRes -> log.info("master details saved in DB."))
.subscribe();
}).subscribe();
}).doOnError(err ->{
log.error("Unable to fetch information from series :: {}", err.getMessage());
Mono.error(new RunTimeException("Unable to fetch information from series :: {}" + err.getMessage()));
}).block();
return Mono.just(response);
}
根据我的理解,你实际上可以让它更简洁,而且你不需要使用 block()。 这是您可以使用的示例代码
return seriesRepo
.findByItemType(request.getItemType())
.switchIfEmpty(Mono.error({YOUR EXCEPTION})))
.flatMap(series -> Mono.just( getBillNumberByType(series) ))
.flatMap(billNo -> {
MasterDetails masterDetails = new MasterDetails();
// operation to copy request info to masterDetails
masterDetails.setBillNo(billNo);
return Mono.just(masterDetails);
}).flatMap(masterDetailsRepo::save)
.flatMap( masterDetails -> {
MasterResponse response = new MasterResponse();
response.setBillNo(masterDetails.getBillNo())
return Mono.just(response);
})