node.js - mongodb中两个请求之间的竞争条件
问题描述
这是电子商务网站,我使用 mongodb 作为数据库,用户可以下订单,每个订单可以有多个产品。Product 是一个单独的表,其中包含每个产品的 quantityLeft。有一种情况,当两个并发请求来并尝试购买相同的产品时,orders 表中的订购商品超过了 product 表中的可用数量。
Product Table
{
_id: '56e33c56ddec541556a61763',
name: 'Chocolate',
quantityLeft: 1
}
如果一次有一个请求,则在产品表中只剩下 1 块巧克力,它工作正常。请求来检查 order.quantity 并处理是否有足够的产品可用。
但是,当 2 个请求恰好同时出现时,请求查询数据库以获取产品并检查 quantityLeft 并发现只有 1 个巧克力可用,并通过检查库存中仍然存在足够数量并下订单。但实际上有 2 个订单,我们的数量只有 1 个。
Order Table
{
_id: '60e33c56ddec541556a61595',
items: [{
_id: '56e33c56ddec541556a61763',
quantity: 1
}]
}
我尝试将这两个查询都放在同一事务中以获取产品详细信息并下订单,但它不起作用。像这样的东西
const session = await mongoose.startSession({ defaultTransactionOptions: { readConcern: { level: 'local' }, writeConcern: { w: 1 } } })
await session.withTransaction(async () => {
const promiseArray = order.items.map((item) => Product.find({ _id: item._id }, { session })
const products = Promise.all(promiseArray)
const productById = {}
products.forEach((product) => {
productById[product._id] = product
})
order.items.forEach((item) => {
if (productById[item].quantityLeft < order.item) {
throw new Error('Not enough quantity')
}
})
await Order.create(order, {session})
}, { readConcern: { level: 'local' }, writeConcern: { w: 1 } });
我正在使用nodejs(14.16),mongodb作为数据库npm包是mongoose(5.9)。
解决方案
推荐阅读
- laravel - Laravel 关系给了我“?” 而不是电子邮件
- python - 从操作系统命令行调用路径上的 .py 文件
- javascript - 如何在 HTML/CSS 中添加特定于设备的变量?
- python-3.x - 为什么在我的 Docker 映像上安装 python-psycopg2 不能防止随后出现“没有名为 'psycopg2' 的模块”错误?
- python - 查找具有连续但奇数日期的百分比差异和差异
- javascript - 如何在 MongoDB 中插入带有子文档的文档
- jquery - jQuery |for 循环创建唯一元素类
- git - `git add -all` 的快捷方式是如何制作的(在终端中)?
- python - 如何使用熊猫数据框按秒重新采样累积的数据并每天重置
- c# - Any(LINQ) 中的语句 lambda