douqing5981 2018-12-30 15:53
浏览 124
已采纳

使用mongo-go-driver与MongoDB的数据不一致

FindOneAndReplace may or may not replace the document in MongoDB. The response indicates that the operation succeeded, but looking into MongoDB it was not updated at all.

The MongoDB server version is MongoDB server version: 3.2.0 This bug is reproducible in Ubuntu 16.04 and macOS Mojave. The target host is Azure CosmosDB.

The driver version is mongo-go-driver@v0.0.17

func (s *Service) DeleteFileMetadata(ctx context.Context, req *pb.DocumentRequest) (*pb.DocumentResponse, error) {
    log.Println("[INFO] Requesting DeleteFileMetadata service")

    if ok := isStateAvailable(); !ok {
        log.Printf("[ERROR] %s
", errServiceUnavailable.Error())
        return nil, status.Error(codes.Unavailable, errServiceUnavailable.Error())
    }

    if err := refreshMongoDBConnection(mongoDBWriter, &conf.DocumentDB.Writer); err != nil {
        log.Printf("[ERROR] %s
", err.Error())
        return nil, status.Error(codes.Internal, err.Error())
    }

    if req == nil {
        log.Printf("[ERROR] %s
", errNilRequest.Error())
        return nil, status.Error(codes.InvalidArgument, errNilRequest.Error())
    }

    fileMetadataParameters := req.GetFileMetadataParameters()
    if fileMetadataParameters == nil || fileMetadataParameters.GetDuid() == "" {

        log.Printf("[ERROR] %s
", errInvalidFileMetadataParameters.Error())
        return nil, status.Error(codes.InvalidArgument, errInvalidFileMetadataParameters.Error())
    }

    if err := ValidateDUID(fileMetadataParameters.GetDuid()); err != nil {
        log.Printf("[ERROR] %s
", err.Error())
        return nil, status.Error(codes.InvalidArgument, err.Error())
    }

    if err := ValidateUUID(fileMetadataParameters.GetUuid()); err != nil {
        log.Printf("[ERROR] %s
", err.Error())
        return nil, status.Error(codes.InvalidArgument, err.Error())
    }

    if err := ValidateFUID(fileMetadataParameters.GetFuid()); err != nil {
        log.Printf("[ERROR] %s
", err.Error())
        return nil, status.Error(codes.InvalidArgument, err.Error())
    }

    if fileMetadataParameters.Media > pb.FileType_VIDEO {
        return nil, status.Error(codes.InvalidArgument, errMediaType.Error())
    }

    log.Printf("[INFO] FileMetadataParameters: 
%v

", pretty.Sprint(req.GetFileMetadataParameters()))

    // Get the specific lock if it already exists, else make the lock
    lock, _ := duidClientLocker.LoadOrStore(fileMetadataParameters.GetDuid(), &sync.RWMutex{})
    // Lock
    lock.(*sync.RWMutex).Lock()
    // Unlock before the function exits
    defer lock.(*sync.RWMutex).Unlock()

    collection := mongoDBWriter.Database(conf.DocumentDB.Name).Collection(conf.DocumentDB.Collection)

    // Find all MongoDB documents for the specific uuid
    filter := bson.NewDocument(
        bson.EC.String("duid", fileMetadataParameters.GetDuid()),
        bson.EC.String("uuid", fileMetadataParameters.GetUuid()),
    )
    bsonResult := collection.FindOne(context.Background(), filter)
    if bsonResult == nil {
        log.Printf("[ERROR] FindOne: %s
", errNoDocumentFound.Error())
        return nil, status.Error(codes.InvalidArgument, errNoDocumentFound.Error())
    }
    documentToUpdate := &pb.Document{}
    if err := bsonResult.Decode(documentToUpdate); err != nil {
        log.Printf("[ERROR] Document not found, duid: %s - uuid: %s - err: %s
",
            fileMetadataParameters.GetDuid(), fileMetadataParameters.GetUuid(), err.Error())

        return nil, status.Errorf(codes.InvalidArgument,
            "Document not found, duid: %s - uuid: %s",
            fileMetadataParameters.GetDuid(), fileMetadataParameters.GetUuid())
    }

    log.Printf("[INFO] Document to update: 
%s

", pretty.Sprint(documentToUpdate))

    switch fileMetadataParameters.Media {
    case pb.FileType_FILE:
        delete(documentToUpdate.GetFileUrlsMap(), fileMetadataParameters.GetFuid())
    case pb.FileType_AUDIO:
        delete(documentToUpdate.GetAudioUrlsMap(), fileMetadataParameters.GetFuid())
    case pb.FileType_IMAGE:
        delete(documentToUpdate.GetImageUrlsMap(), fileMetadataParameters.GetFuid())
    case pb.FileType_VIDEO:
        delete(documentToUpdate.GetVideoUrlsMap(), fileMetadataParameters.GetFuid())
    default:
        return nil, status.Error(codes.InvalidArgument, errMediaType.Error())
    }
    documentToUpdate.UpdateTimestamp = time.Now().UTC().Unix()

    // option to return the the document after update
    option := findopt.ReplaceOneBundle{}
    result := collection.FindOneAndReplace(context.Background(), filter, documentToUpdate,
        option.ReturnDocument(mongoopt.After))

    // Extract the updated MongoDB document
    if result == nil {
        log.Printf("[ERROR] Extracting updated document, duid: %s - uuid: %s
",
            documentToUpdate.GetDuid(), documentToUpdate.GetUuid())

        return nil, status.Errorf(codes.Internal,
            "Extracting updated document duid: %s - uuid: %s",
            documentToUpdate.GetDuid(), documentToUpdate.GetUuid())
    }

    document := &pb.Document{}
    if err := result.Decode(document); err != nil {
        log.Printf("[ERROR] %s
", err.Error())
        return nil, status.Errorf(codes.Internal, err.Error())
    }

    log.Printf("[INFO] Updated document: 
%s

", pretty.Sprint(document))
    log.Printf("[INFO] Success deleting file metadata in document, duid: %s - uuid: %s - fuid: %s
",
        document.GetDuid(), document.GetUuid(), fileMetadataParameters.GetFuid())

    return &pb.DocumentResponse{
        Status:  &pb.DocumentResponse_Code{Code: uint32(codes.OK)},
        Message: codes.OK.String(),
        Data:    document,
    }, nil
}

I expect that response reflects the actual state of the data in the MongoDB server.

Let us say I want to delete a filemetadata with fuid of 05ce38e7-a29a-485f-bf20-eef3501867f0

I get this response indicating that it was deleted. The response was decoded from result := collection.FindOneAndReplace(context.Background(), filter, documentToUpdate, option.ReturnDocument(mongoopt.After))

 ImageUrlsMap:         {217706a5-2f88-4eb2-8a93-c1426c5ac944: "https://hwscdevstorage.blob.core.windows.net/images/hulkgif.png",
                        4ff30392-8ec8-45a4-ba94-5e22c4a686df: "https://hwscdevstorage.blob.core.windows.net/images/Rotating_earth_(large).gif"},
 AudioUrlsMap:         {4ff30392-8ec8-45a4-ba94-5e22c4a686df: "https://hwscdevstorage.blob.core.windows.net/audios/Milad Hosseini - Deli Asheghetam [128].mp3",
                        8fe5fea7-f683-4198-8c94-f27601a5e2d0: "https://hwscdevstorage.blob.core.windows.net/audios/Seger_Conga_CaboMexico_Tag_Acousonde_20140313_112313_8000_3_BreedingMigrating.wav"},
 VideoUrlsMap:         {4ff30392-8ec8-45a4-ba94-5e22c4a686de: "https://hwscdevstorage.blob.core.windows.net/videos/videoplayback.wmv",
                        4ff30392-8ec8-45a4-ba94-5e22c4a686df: "https://hwscdevstorage.blob.core.windows.net/videos/videoplayback.mp4",
                        e525ca9c-9813-4286-abda-8bd0eb6e94b4: "https://hwscdevstorage.blob.core.windows.net/videos/pusheen.mp4"},
 FileUrlsMap:          {13df1afa-4eee-470e-b9e2-60b2a7584994: "https://hwscdevstorage.blob.core.windows.net/videos/videoplayback.wmv",
                        4ff30392-8ec8-45a4-ba94-5e22c4a686df: "https://hwscdevstorage.blob.core.windows.net/videos/videoplayback.mp4",
                        b7a16e10-ac03-468f-9b6d-dcc684d1147f: "https://hwscdevstorage.blob.core.windows.net/videos/pusheen.mp4"},
 RecordTimestamp:      1514764800,
 CreateTimestamp:      1539831496,
 UpdateTimestamp:      1546183549,
 IsPublic:             true,
 XXX_NoUnkeyedLiteral: {},
 XXX_unrecognized:     [],
 XXX_sizecache:        0}

2018/12/30 07:25:49 [INFO] Success deleting file metadata in document, duid: 1ChHfmKs8GX7D1XVf61lwVdisWf - uuid: 0XXXXSNJG0MQJHBF4QX1EFD6Y3 - fuid: 05ce38e7-a29a-485f-bf20-eef3501867f0

But if I go to Azure CosmosDB or in my local server, it is still there. screenshot

  • 写回答

1条回答 默认 最新

  • dongshuql24533 2019-01-02 08:48
    关注

    Unable to reproduce bug in MongoDB Server 3.4

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥30 Matlab打开默认名称带有/的光谱数据
  • ¥50 easyExcel模板 动态单元格合并列
  • ¥15 res.rows如何取值使用
  • ¥15 在odoo17开发环境中,怎么实现库存管理系统,或独立模块设计与AGV小车对接?开发方面应如何设计和开发?请详细解释MES或WMS在与AGV小车对接时需完成的设计和开发
  • ¥15 CSP算法实现EEG特征提取,哪一步错了?
  • ¥15 游戏盾如何溯源服务器真实ip?需要30个字。后面的字是凑数的
  • ¥15 vue3前端取消收藏的不会引用collectId
  • ¥15 delphi7 HMAC_SHA256方式加密
  • ¥15 关于#qt#的问题:我想实现qcustomplot完成坐标轴
  • ¥15 下列c语言代码为何输出了多余的空格