You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vert.x检查Future状态时succeeded与isComplete均返回false问题求助

问题根因

核心原因是异步操作的时序问题:

  • Vert.x的数据库操作是完全异步非阻塞的,你调用executeBatch方法时,仅仅是将数据库操作请求提交到了内部队列,方法会立即返回,不会等待数据库实际执行完毕。你返回的promise.future()在方法返回时还处于未完成状态,只有数据库操作执行结束触发回调时,才会调用promise.complete()修改Future状态。
  • 从你贴的日志也能验证时序:打印Future状态的时间是11:42:41.709,而数据库插入成功的日志打印时间是11:42:41.914,检查状态的操作比数据库实际执行完成早了200ms,此时Future自然是未完成、未成功的状态。

注意事项

不要用同步的方式直接检查刚返回的异步Future的状态,异步操作的结果必须通过Future的回调函数、或者链式组合操作来获取。

改造方案

如果你需要在generateChildSerial执行完成后做后续处理/日志打印,可以给Future绑定onComplete回调,回调会在异步操作结束后自动触发:

createJob(context)
    .compose(jobID -> {
        LOG.debug("jobID "+jobID);
        Future<Void> generateChildSerial = generateChildSerial(context, jobID);
        // 绑定回调,等异步操作完成后再打印状态
        generateChildSerial.onComplete(ar -> {
            LOG.debug("generateChildSerial.succeeded() "+ar.succeeded()+" "+ar.result());
            LOG.debug("generateChildSerial.isComplete() "+ar.isComplete());
        });
        return generateChildSerial;
    });

隐藏Bug修复

你现有generateChildSerial方法里的回调,不管数据库操作成功还是失败,都调用了promise.complete(),这会导致上层永远拿到成功状态的Future,无法感知到数据库插入失败的异常,需要修改为失败时传递异常:

db
  .preparedQuery(sql)
  .executeBatch(batch, res -> {
  if (res.succeeded()) {
    RowSet<Row> rows = res.result();
    LOG.info("rows.rowCount():"+ rows.rowCount());
    promise.complete(); // 成功才complete
  } else {
    System.out.println("Batch failed " + res.cause());
    promise.fail(res.cause()); // 失败时调用fail传递异常
  }
});

return promise.future();

内容的提问来源于stack exchange,提问作者ZAJ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.23 16:57:01