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

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

报告相同问题?

悬赏问题

  • ¥100 微信小程序跑脚本授权的问题
  • ¥100 房产抖音小程序苹果搜不到安卓可以付费悬赏
  • ¥15 STM32串口接收问题
  • ¥15 腾讯IOA系统怎么在文件夹里修改办公网络的连接
  • ¥15 filenotfounderror:文件是存在的,权限也给了,但还一直报错
  • ¥15 MATLAB和mosek的求解问题
  • ¥20 修改中兴光猫sn的时候提示失败
  • ¥15 java大作业爬取网页
  • ¥15 怎么获取欧易的btc永续合约和交割合约的5m级的历史数据用来回测套利策略?
  • ¥15 有没有办法利用libusb读取usb设备数据