【发布时间】:2018-12-30 15:53:50
【问题描述】:
FindOneAndReplace 可能会也可能不会替换 MongoDB 中的文档。 响应表明操作成功,但查看 MongoDB 它根本没有更新。
MongoDB服务器版本是MongoDB服务器版本:3.2.0 此错误可在 Ubuntu 16.04 和 macOS Mojave 中重现。 目标主机是 Azure CosmosDB。
驱动版本是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\n", errServiceUnavailable.Error())
return nil, status.Error(codes.Unavailable, errServiceUnavailable.Error())
}
if err := refreshMongoDBConnection(mongoDBWriter, &conf.DocumentDB.Writer); err != nil {
log.Printf("[ERROR] %s\n", err.Error())
return nil, status.Error(codes.Internal, err.Error())
}
if req == nil {
log.Printf("[ERROR] %s\n", errNilRequest.Error())
return nil, status.Error(codes.InvalidArgument, errNilRequest.Error())
}
fileMetadataParameters := req.GetFileMetadataParameters()
if fileMetadataParameters == nil || fileMetadataParameters.GetDuid() == "" {
log.Printf("[ERROR] %s\n", errInvalidFileMetadataParameters.Error())
return nil, status.Error(codes.InvalidArgument, errInvalidFileMetadataParameters.Error())
}
if err := ValidateDUID(fileMetadataParameters.GetDuid()); err != nil {
log.Printf("[ERROR] %s\n", err.Error())
return nil, status.Error(codes.InvalidArgument, err.Error())
}
if err := ValidateUUID(fileMetadataParameters.GetUuid()); err != nil {
log.Printf("[ERROR] %s\n", err.Error())
return nil, status.Error(codes.InvalidArgument, err.Error())
}
if err := ValidateFUID(fileMetadataParameters.GetFuid()); err != nil {
log.Printf("[ERROR] %s\n", 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: \n%v\n\n", 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\n", 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\n",
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: \n%s\n\n", 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\n",
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\n", err.Error())
return nil, status.Errorf(codes.Internal, err.Error())
}
log.Printf("[INFO] Updated document: \n%s\n\n", pretty.Sprint(document))
log.Printf("[INFO] Success deleting file metadata in document, duid: %s - uuid: %s - fuid: %s\n",
document.GetDuid(), document.GetUuid(), fileMetadataParameters.GetFuid())
return &pb.DocumentResponse{
Status: &pb.DocumentResponse_Code{Code: uint32(codes.OK)},
Message: codes.OK.String(),
Data: document,
}, nil
}
我希望响应反映 MongoDB 服务器中数据的实际状态。
假设我要删除 fuid 为 05ce38e7-a29a-485f-bf20-eef3501867f0 的文件元数据
我收到此回复,表明它已被删除。响应解码自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
但如果我转到 Azure CosmosDB 或我的本地服务器,它仍然存在。 screenshot
【问题讨论】:
-
发生的时候非常随机。有时它确实可以完成工作。我没有看到任何竞争条件,因为我锁定了文档以进行写入。一个月前使用godoc.org/github.com/mongodb/mongo-go-driver/mongo 运行良好
-
您的数据库服务器上是否发生了复制延迟?
-
我最近刚刚优化了我的 GRPC 服务器。它运行我所有的单元测试从 5 分钟到现在不到一分钟。我正在阅读来自dzone.com/articles/mongodb-replication-lag-and 的有关突发写入的内容
-
您提到在本地 MongoDB 服务器和 Cosmos 上进行测试。 Cosmos 的 MongoDB API 是模仿 MongoDB API 的服务器实现,但行为可能不同。为了澄清您的问题的范围,您能否确认您是否在本地 MongoDB 服务器上获得了预期的结果,或者此问题是否特定于 Cosmos API?另外,您使用的是什么版本的 MongoDB Go 驱动程序?
-
@Stennie CosmosDB 和本地都会发生这种情况。我目前正在使用 mongodb/mongo-go-driver@v0.0.17。今晚我会尝试 0.1.0。
标签: mongodb go azure-cosmosdb mongo-go