C#操作MongoDB时如何为文档的String字段追加字符?
问题原因
当前你使用的「先查询Log字段、内存拼接、再写回数据库」的逻辑属于非原子操作,多个异步请求并发执行时,后发起的请求会拿到还未被前请求更新的旧Log值,拼接后覆盖前序请求的更新,最终导致部分日志内容丢失。
解决方案
MongoDB 4.2及以上版本支持在更新操作中使用聚合表达式,你可以直接用$concat操作符在数据库层面完成Log字段的内容追加,全程仅需要一次原子更新,无需提前查询文档,彻底避免并发覆盖问题。
对应C#代码示例如下:
var collection = db.GetCollection<ServerEntity>(ServerCollectionName); var filter = Builders<ServerEntity>.Filter.Eq(server => server.ID, id); // 原子追加日志的更新定义 var update = Builders<ServerEntity>.Update.Pipeline( new BsonDocument[] { new BsonDocument("$set", new BsonDocument("Log", new BsonDocument("$concat", new BsonArray { // 兼容Log为null的场景,如果Log一定不为空可以去掉$ifNull逻辑 new BsonDocument("$ifNull", new BsonArray { "$Log", "" }), message } ) ) ) } ); await collection.UpdateOneAsync(filter, update);
额外说明
如果需要在更新完成后直接拿到最新的文档内容,可以将UpdateOneAsync替换为FindOneAndUpdateAsync,配置返回更新后的文档即可,整个操作仍然是原子的,不会引入并发问题。
内容的提问来源于stack exchange,提问作者MeD
相关产品推荐
相关产品推荐

