[英]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.