【问题标题】:Handling Exception when bulkwrite with ordered as false in MongoDB java在 MongoDB java 中使用 ordered as false 进行批量写入时处理异常
【发布时间】:2016-05-12 03:17:29
【问题描述】:

我正在使用 Mongo DB java 驱动程序:

collection.bulkWrite(documents);

我有 100 万条记录要插入。如果其中一条记录的插入失败,那么在第一次失败时,剩余的记录将不会被插入。 为了避免这种情况,我发现有BulkWriteOptionsordered 作为false;

collection.bulkWrite(documents, new BulkWriteOptions().ordered(false) )

如果上述操作出现异常,能否获取bulkwrite失败的记录列表,是否可以重新尝试插入这些记录?

【问题讨论】:

    标签: mongodb mongodb-query mongodb-java


    【解决方案1】:

    我认为您正在寻找类似的东西..

    BulkWriteOptions bulkWriteOptions = new BulkWriteOptions();
    bulkWriteOptions.ordered(true);
    
    BulkWriteResult bulkWriteResult = null;
    try {
        bulkWriteResult = mongoCollection.bulkWrite(updateDocuments,
                bulkWriteOptions);
    } catch (BulkWriteException e) {
        List<BulkWriteError> bulkWriteErrors = e.getWriteErrors();
        for (BulkWriteError bulkWriteError : bulkWriteErrors) {
            int failedIndex = bulkWriteError.getIndex();
            Long failedEntity = entityList.get(failedIndex);
            System.out.println("Failed record: " + failedEntity);
            //handle rollback
        }
    }
    

    【讨论】:

      【解决方案2】:

      所有失败的 bulkWrite 操作都会在返回文档的数组中报告,以及插入失败的完整文档。例如,这段代码通过java驱动:

      MongoCollection<Document> collection = database.getCollection("bulk");
      
      List<WriteModel<Document>> writes = new ArrayList<WriteModel<Document>>();
       writes.add(new InsertOneModel<Document>(new Document("_id", 1)));
       writes.add(new InsertOneModel<Document>(new Document("_id", 2)));
       writes.add(new InsertOneModel<Document>(new Document("_id", 2)));
       writes.add(new InsertOneModel<Document>(new Document("_id", 4)));
      BulkWriteResult bulkWriteResult = collection.bulkWrite(writes);
      
      System.out.println(bulkWriteResult.toString());
      

      返回这个:

      Exception in thread "main" com.mongodb.MongoBulkWriteException: 
        Bulk write operation error on server localhost:27017. Write errors:
        [BulkWriteError{index=2, code=11000, message='E11000 duplicate key 
        error collection: test.bulk index: _id_ dup key: { : 2 }',
        details={ }}].
      

      您没有提及您使用的是哪个版本的 MongoDB,但如果您想进一步了解,这里是无序 bulkWrites 的 3.2 版手动条目:https://docs.mongodb.org/manual/core/bulk-write-operations/

      但是,如果您所说的“异常”是指在加载操作过程中客户端或 mongod 进程崩溃,或者发生硬件或网络事件,则不会有从 bulkWrite 干净退出,因此没有 bulkWriteResult输出如上。无序bulkWrites并行执行操作,不一定按输入顺序执行,分片集合和分布式集群更复杂,因此无法准确知道崩溃前完成了哪些操作。唯一的解决方案是重复整个工作,这通常需要您删除所有第一次成功插入的文档。

      如果您正在加载到一个新的或空的集合,您可以简单地删除并重新创建它。如果有一个带有索引的唯一键,您可以重复加载,因为第一次插入 OK 的文档将作为重复文件被拒绝。否则,您将不得不运行清理作业以删除所有可能/应该在开始重新加载尝试之前插入的文档,如果它们不容易识别,则可能会出现问题。

      此方案的最佳方法是将大型加载操作分解为更小的部分,因此您有四个加载作业,每个作业包含四分之一的数据(或二十个每个包含 5% 的数据,依此类推)。以这种方式设计加载过程需要付出更多的努力,但使用 5% 的总数据重复一项作业比必须重复一个在 95% 标记处失败的加载要快得多。

      如果为每个作业添加不同值的 loadNum 字段,则可以使用 count(“loadNum”:n) 来确认所有文档已加载,而 remove(“loadNum”:n) 将删除仅部分成功的作业中的所有文档。

      【讨论】:

        猜你喜欢
        • 2012-07-03
        • 2019-07-19
        • 2015-09-29
        • 1970-01-01
        • 1970-01-01
        • 2020-03-04
        • 2021-12-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多