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

预订系统超时机制实现方案及相关场景问题解析

酒店预订超时机制实现方案

一、核心超时锁定实现

用Redis带TTL的键值对是行业通用方案,具体流程:

  • 用户点击预订按钮后,后端生成唯一的临时锁定订单ID,将「客房ID、用户ID、锁定开始时间」作为value存入Redis,设置20分钟TTL,key命名可以用hotel:lock:room:{room_id}:user:{user_id},方便快速查询和管理。
  • 同时在数据库的客房表或锁定记录表中,同步记录lock_user_id、lock_expire_time字段,做双重保障(避免Redis宕机导致状态丢失)。
  • 释放客房的两种触发方式:
    • Redis过期通知:开启Redis的notify-keyspace-events Ex配置,后端监听__keyevent@0__:expired事件,当锁定键过期时,自动执行释放客房的逻辑(清空数据库中的锁定字段,标记客房为可预订)。
    • 定时任务兜底:用定时任务(比如Quartz、XXL-Job)每隔5分钟扫描数据库中的锁定记录,清理已过期且未转正的锁定,避免Redis通知丢失的情况。

二、UI倒计时展示

前端实现倒计时的同时,必须配合后端校验:

  • 用户进入预订页面时,后端返回「锁定开始时间」和「超时时长(20分钟)」,前端在本地计算剩余时间,用setInterval每秒更新倒计时显示。
  • 倒计时结束后,前端自动禁用支付按钮,提示“预订超时,请重新发起预订”。
  • 关键校验:用户提交支付或确认订单时,后端必须再次检查Redis或数据库的lock_expire_time,确认锁定未过期,防止前端篡改本地时间绕过限制。

三、第三方支付超时的冲突处理

用户跳转到Stripe/PayPal后TTL到期、客房被释放,但后续完成支付的情况,是生产环境必须处理的场景,常用方案:

1. 支付前延长锁定时长

当用户点击「去支付」跳转第三方平台前,后端主动将该锁定的TTL延长至30-45分钟(根据第三方支付的平均耗时调整),同时更新数据库的lock_expire_time。可以限制延长次数(比如最多1次),避免恶意占用客房。

2. 支付回调时的兜底校验

第三方支付平台回调后端时,按以下逻辑处理:

  • 先查询该临时锁定对应的客房状态:
    • 如果客房仍未被其他用户预订:直接将临时锁定转为正式订单,完成后续流程。
    • 如果客房已被他人预订:立即触发退款流程(调用Stripe/PayPal的退款API),同时通过短信/站内信通知用户“客房已被他人预订,已为您全额退款,请重新选择其他客房”。

3. 增设「支付中」过渡状态

将锁定拆分为两个阶段:

  • 第一阶段:填写信息阶段,20分钟锁定,此时其他用户可以看到客房“已被锁定”。
  • 第二阶段:用户发起支付后,切换为「支付中」状态,设置更长的TTL(比如40分钟),此时其他用户看到客房“支付中”,无法发起预订。该状态下即使原锁定TTL到期,也不会释放客房,直到支付完成或支付超时(比如40分钟)再处理。

额外注意点

  • 要处理Redis宕机的情况:此时完全依赖数据库的lock_expire_time字段,定时任务会清理过期锁定,保证客房不会被永久占用。
  • 用户主动取消预订时,后端要主动删除Redis的锁定键,并清空数据库的锁定字段,及时释放客房。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 15:50:28