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

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

    报告相同问题?

    悬赏问题

    • ¥15 I350 Gigabit Network
    • ¥15 关于#abap#的问题,请各位专家解答!
    • ¥20 内网通过公网访问外网问题
    • ¥20 谁有这个东西 继续教育的
    • ¥15 怎么使请求通过cors
    • ¥15 WDM 驱动ACPI 相关疑问
    • ¥15 prism 跨窗体共享数据绑定 wpf
    • ¥15 hdl designer突然用不了系统的moduleware组件,请问有人遇到或者怎么解决吗?
    • ¥15 0基础计算机毕设,应该从哪开始?
    • ¥60 使用DKT40脑图划分ROI区域