You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何处理酒店房间API并发请求,避免重复分配房间?

解决并发请求下酒店房间重复分配的问题

你的核心问题是并发场景下房间被重复分配,根源在于代码存在语法错误,同时未充分利用MongoDB原子操作的特性来保障可靠性,以下是具体修复方案:

1. 修复语法错误

你的$set字段中,isBusy: true后缺少逗号,会导致更新操作失效——房间的isBusy状态根本没被修改,所有请求都会反复匹配到同一个空闲房间:

// 错误写法
$set:{
    isBusy: true
    customer: request.body.customer_id
}

// 正确写法(添加逗号)
$set:{
    isBusy: true,
    customer: request.body.customer_id
}

2. 确保findOneAndUpdate的原子性与正确性

findOneAndUpdate本身是MongoDB的原子操作,但需明确指定选项,保证只更新第一个匹配的空闲房间,并返回正确的文档:

const db = await ConnectToDatabase(process.env.MONGODB_URI);
const collection2 = db.collection('rooms');

// 指定returnDocument: 'before' 返回更新前的房间信息,upsert: false 避免创建新文档
const result = await collection2.findOneAndUpdate(
    { isBusy: false },
    { 
        $set: {
            isBusy: true,
            customer: request.body.customer_id
        }
    },
    { returnDocument: 'before', upsert: false }
);

if (!result) {
    return response.status(200).json({
        status: "FAIL",
        msg: "No available rooms"
    });
}

return response.status(200).json({
    status: "SUCCESS",
    room: result.room_number
});

3. 额外优化建议

  • 添加索引:给isBusy字段创建单键索引,提升并发下的查询效率,减少请求排队时间:
    // 集合初始化时执行一次即可
    await collection2.createIndex({ isBusy: 1 });
    
  • 使用写关注:如果需要更高的数据一致性,可指定writeConcern选项,确保写入操作被MongoDB集群多数节点确认:
    const result = await collection2.findOneAndUpdate(
      { isBusy: false },
      { $set: { isBusy: true, customer: request.body.customer_id } },
      { returnDocument: 'before', upsert: false, writeConcern: { w: 'majority' } }
    );
    
  • 统一用POST请求:分配房间是修改状态的写操作,GET请求是幂等的,建议只使用POST处理房间分配,避免浏览器或CDN重复发送GET请求导致意外。

内容的提问来源于stack exchange,提问作者SrMilton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 12:27:36