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

mongo-java-driver运行正常但mongodb-driver-reactivestreams无法插入数据

问题根因

你的JVM主线程在异步插入操作执行完成前就直接退出了,导致未发送的数据库请求直接被销毁,所以文档没有插入成功。同步驱动的insertOne是阻塞方法,会等待插入操作完成后才继续往下执行,因此可以正常插入。

你提供的两种异步写法分别存在以下问题:

  • 第一种带订阅逻辑的写法:订阅后插入操作在MongoDB驱动的后台IO线程执行,主线程没有等待操作完成就直接结束进程,插入请求还未发送到数据库进程就已终止
  • 第二种写法:mongodb-driver-reactivestreams的插入方法返回的是Publisher,属于懒执行组件,你没有调用subscribe方法订阅的情况下,不会触发任何实际的数据库操作。

解决方法

  1. 所有异步操作必须显式调用subscribe订阅才能触发执行
  2. 单测/main方法执行的测试场景下,需要加锁等待异步操作完成后再退出主线程,参考修改后的代码:
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

// ...省略其他代码
CountDownLatch latch = new CountDownLatch(1);

MongoClient mongoClient1 = MongoClients.create();
MongoDatabase database = mongoClient1.getDatabase("nifi");
Document doc = new Document("name", "MongoDB")
        .append("type", "database")
        .append("count", 1)
        .append("info", new Document("x", 203).append("y", 102));
Publisher<Success> publisher = database.getCollection("log").insertOne(doc);

publisher.subscribe(new Subscriber<Success>() {
    @Override
    public void onSubscribe(final Subscription s) {
        s.request(1); 
        System.out.println("开始执行插入");
    }

    @Override
    public void onNext(final Success success) {
        System.out.println("插入成功");
    }

    @Override
    public void onError(final Throwable t) {
        System.out.println("插入报错:" + t.getMessage());
        t.printStackTrace();
        latch.countDown();
    }

    @Override
    public void onComplete() {
        System.out.println("操作完成");
        latch.countDown();
    }
});

// 主线程最多等待10秒,避免异常情况下无限阻塞
latch.await(10, TimeUnit.SECONDS);
// 关闭客户端释放资源
mongoClient1.close();

如果是在Web服务、定时任务这类常驻进程的场景下使用,不需要加CountDownLatch等待逻辑,因为主线程不会主动退出,异步操作会在后台正常执行完成。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 10:39:02