Java Vert.x报错Result is already complete: succeeded 多数据库操作异常求解
Vert.x多步数据库操作
Result is already complete异常排查 异常根因
- 你当前代码完全没有做异常分支判断:所有
onComplete回调都没有校验异步操作的执行结果状态,直接调用.result()取值。如果前面任意一步数据库操作(delete_1/delete_2/delete_3)执行失败,调用失败状态Future的.result()方法会直接抛出未捕获的IllegalStateException。 - 未捕获的异常会被Vert.x上下文捕获,自动尝试将你定义的
deletedPromise标记为失败状态;但你的回调逻辑不会因此中断,仍然会继续执行后续操作,最终走到deleted.complete(id)时,就会尝试给已经完成(失败状态)的Promise再次赋值,触发Result is already complete报错。 - 额外问题:多层嵌套回调(回调地狱)的写法可读性极差,也极易漏写异常分支的处理逻辑。
修复方案
方案1:推荐使用Future链式组合(无嵌套、自动传递异常)
Vert.x的compose操作符会自动处理异常传递,前面任意一步操作失败,整个异步链会直接返回失败Future,不会执行后续逻辑,也不会出现重复操作Promise的问题:
public Future<String> delete(String id) { return delete_1(id) // 第一步执行成功后执行第二步 .compose(delete1Res -> delete_2(id)) // 第二步执行成功后并行执行第三、第四步 .compose(delete2Res -> CompositeFuture.all( delete_3_InvRaw_Mfg(delete2Res), delete_4_InvRaw_Company(delete2Res) )) // 所有步骤成功后返回id .map(unused -> id); }
方案2:如果保留嵌套回调写法,必须每个步骤加状态判断
每个onComplete回调都先校验执行结果,失败时直接给Promise赋值并中断后续逻辑:
public Future<String> delete(String id) { Promise<String> deleted = Promise.promise(); delete_1(id).onComplete(ar1 -> { if (ar1.failed()) { deleted.fail(ar1.cause()); return; } delete_2(id).onComplete(ar2 -> { if (ar2.failed()) { deleted.fail(ar2.cause()); return; } String delete2Res = ar2.result(); delete_3_InvRaw_Mfg(delete2Res).onComplete(ar3 -> { if (ar3.failed()) { deleted.fail(ar3.cause()); return; } delete_4_InvRaw_Company(delete2Res).onComplete(ar4 -> { if (ar4.failed()) { deleted.fail(ar4.cause()); return; } deleted.complete(id); }); }); }); }); return deleted.future(); }
内容的提问来源于stack exchange,提问作者ZAJ
相关产品推荐
相关产品推荐

