简体   繁体   English

与 MongoDB 和 NodeJs 的并发写入冲突

[英]Concurrent WriteConflict with MongoDB and NodeJs

I'm creating an application that serves transportation order, while I'm stress testing the application by injecting about 100 orders simultaneously, the mongodb hits WriteConflict due to the numeric sequence id ( nid it is required) that I created using the hook.我正在创建一个服务于运输订单的应用程序,同时我通过同时注入大约 100 个订单来对应用程序进行压力测试, mongodb由于我使用钩子创建的数字序列 ID(它是必需的)而命中 WriteConflict。 I have tried to add ?retryWrites=true&w=majority into the connection URI and set those in the transaction level, but none of those work.我尝试将?retryWrites=true&w=majority添加到连接 URI 中并将其设置在事务级别,但这些都不起作用。 May I know any parts that I'm missing and should give a try (Knowing that is critical section, and using lock/queue should fix, but want to know any other way)?我可以知道我遗漏的任何部分并且应该尝试一下(知道这是关键部分,并且使用锁/队列应该可以修复,但想知道任何其他方式)? Thank you very much.非常感谢。

The schema for sequence and order (will keep _id that default created, and mongoose did the thing so haven't mention in the schema)序列和顺序的架构(将保留默认创建的_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
  }
);

Pre saving hook to assign an numeric id index of hex id to the schema预保存挂钩以将十六进制 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();
});

The code that create the order model and save创建订单 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;
}

The problem is that all of your transactions modify the same document in the findOneAndUpdate.问题是您的所有事务都修改了 findOneAndUpdate 中的同一个文档。

Try acquiring your sequence number before starting the transaction.在开始交易之前尝试获取您的序列号。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM