You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MongoDB乐观并发结合upsert:单原子操作保存同ID最新序列号消息

原子Upsert实现方案

核心逻辑

MongoDB单文档写操作天然具备原子性,我们只需把「仅当新消息sequenceNumber更大才写入」的规则加入过滤条件,配合upsert参数,即可完全替代原有先查后写的逻辑,彻底避免多节点并发的竞态问题,同时性能更优。

原生MongoDB语法

db.your_collection.updateOne(
  // 过滤条件:匹配id,且现有文档的sequenceNumber小于新值
  {
    "_id": newDoc.id,
    "sequenceNumber": { $lt: newDoc.sequenceNumber }
  },
  // 写入完整新文档
  {
    $set: {
      "sequenceNumber": newDoc.sequenceNumber,
      "data": newDoc.data
      // 其余字段按需补充
    }
  },
  { upsert: true }
)

执行逻辑说明:

  • 文档不存在时:过滤条件无匹配,触发upsert直接插入新文档
  • 文档存在且现有sequenceNumber < 新值:过滤条件匹配,执行更新
  • 文档存在且现有sequenceNumber >= 新值:过滤条件不匹配,不执行任何操作

.NET 实现代码

// 定义过滤条件
var filter = Builders<YourDocumentClass>.Filter.And(
    Builders<YourDocumentClass>.Filter.Eq(doc => doc.Id, document.Id),
    Builders<YourDocumentClass>.Filter.Lt(doc => doc.SequenceNumber, document.SequenceNumber)
);

// 执行原子替换+upsert
await _collection.ReplaceOneAsync(
    filter: filter,
    replacement: document,
    options: new ReplaceOptions { IsUpsert = true }
);

优势

  • 全程原子操作,无并发竞态问题,完全适配多节点部署场景
  • 减少一次数据库查询交互,吞吐量更高,应对每秒数百条消息毫无压力
  • 代码更简洁,无需处理查询后的分支判断逻辑

内容的提问来源于stack exchange,提问作者Michael D.

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 03:48:03