簡體   English   中英

與 MongoDB 和 NodeJs 的並發寫入沖突

[英]Concurrent WriteConflict with MongoDB and NodeJs

我正在創建一個服務於運輸訂單的應用程序,同時我通過同時注入大約 100 個訂單來對應用程序進行壓力測試, mongodb由於我使用鈎子創建的數字序列 ID(它是必需的)而命中 WriteConflict。 我嘗試將?retryWrites=true&w=majority添加到連接 URI 中並將其設置在事務級別,但這些都不起作用。 我可以知道我遺漏的任何部分並且應該嘗試一下(知道這是關鍵部分,並且使用鎖/隊列應該可以修復,但想知道任何其他方式)? 非常感謝。

序列和順序的架構(將保留默認創建的_id,並且 mongoose 做了這件事,所以架構中沒有提到)

const SequenceSchema = new Schema<ISequenceDoc>(
  {
    collectionName: {
      type: String,
      trim: true,
      required: true
    },
    nid: {
      type: Number,
      required: true
    }
  },
  {
    collection: 'sequences',
    timestamps: true
  }
);

const OrderSchema = new Schema<IOrderDoc>(
  {
    name: {
      type: String,
      trim: true,
      required: true
    },
    nid: {
      type: Number
    }
  },
  {
    collection: 'orders',
    timestamps: true
  }
);

預保存掛鈎以將十六進制 id 的數字 id 索引分配給模式

OrderSchema.pre('save', async function(next) {
    if (this.isNew) {
      const data = await this.db.model<ISequenceDoc>('Sequence').findOneAndUpdate(
        {
          collectionName: this.collection.collectionName
        },
        {
          $inc: { nid: 1 }
        },
        {
          upsert: true,
          new: true,
          session: this.$session()
        }
      );
      this.set('nid', data.nid);
    }
    next();
});

創建訂單 model 並保存的代碼

async createOrder(orderInfo) => {
const session = await this.connection.startSession();
session.startTransaction({
  readConcern: {
    level: 'majority'
  },
  writeConcern: {
    w: 'majority',
    j: true
  }
});
......
await order.save({session});
await session.commitTransaction();
return order;
}

問題是您的所有事務都修改了 findOneAndUpdate 中的同一個文檔。

在開始交易之前嘗試獲取您的序列號。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM