繁体   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