从购票系统看后端业务逻辑:Session、锁座与超时释放

🥰个人主页:会编程的土豆(欢迎来访)

💎作者简介:后端学习者

❄️个人专栏:数据结构与算法,数据库,leetcode

✨那些你一个人走过的夜路,终将化作照亮未 来的光

做业务后端一段时间后会发现:CRUD 谁都会写,真正体现设计的是「规则怎么落库、并发怎么防、状态怎么收敛」。本文用一个影院票务类项目的思路,把几块常见业务逻辑拆开讲------偏概念,方便对照自己的代码理解。


一、后端到底在护什么

票务核心卖的不是「电影」这个抽象概念,而是:

某场次 + 某些座位 + 一笔订单

所以后端要保证的大致是:

  1. 同一座位不能卖给两个人(防超卖)
  2. 选座后未支付不能永久占着(要超时释放)
  3. 订单和座位状态要一致(不能有单没座、有座没单)
  4. 能认出「当前请求是谁」(登录态)

下面按模块说。


二、登录态:Cookie + Session

HTTP 是无状态的,每次请求默认互不相认。常见做法是:

  • 浏览器:Cookie 里存一个 Session ID(随机串)
  • 服务器:用这个 ID 查到「当前用户是谁」

Session 内容可以放在:

存储 特点
内存 map 实现简单;进程重启丢失;多机难共享
数据库 可持久
Redis 线上常见,快且好过期

为什么不把完整用户信息直接塞进 Cookie?

  • 浏览器侧用户可篡改、也可能被 XSS 偷到
  • 服务器侧保管用户信息更可控;客户端只持有一张「号码牌」

补充:

  • Cookie 常设 HttpOnly,降低 JS 读取风险
  • 同一浏览器配置下 Cookie 共享,所以多个窗口一般不能同时登录两个账号;无痕窗口或不同浏览器才是两套 Cookie

一句话:浏览器持 ID,服务器持用户信息。


三、下单:事务 + 行锁 + 业务锁

选座下单时,通常要同时做两件事:

  1. 创建待支付订单
  2. 把座位改成「锁定」

1. 为什么要事务(Transaction)

这两步必须原子完成:要么都成功,要么都失败。

否则可能出现:

  • 有订单,座位没锁上
  • 座位锁了,订单没建成功

事务里任何一步出错就回滚,避免脏数据。

2. 为什么还要行锁(SELECT ... FOR UPDATE)

防止并发下两人同时读到「座位空闲」并都下单成功。

典型过程:

  1. A 对座位行加 FOR UPDATE,检查空闲,创建订单并锁定
  2. B 同时来,在行锁上等待
  3. A 提交后释放行锁
  4. B 再读,发现已锁定/已售,业务失败返回

行锁解决的是「同一瞬间的并发写冲突」。

3. 业务锁字段是干什么的

行锁在事务结束后就释放了。座位被谁占用、占用到几点,要靠业务字段长期表达,例如:

  • status:空闲 / 锁定 / 已售
  • lock_user_id:谁锁的
  • lock_until:锁到什么时候
  • 订单上的 pay_deadline:支付截止时间

可以记成:

行锁防并发;业务字段表达占用规则与超时。


四、「15 分钟」到底怎么实现

产品说「锁定 15 分钟未支付自动取消」,实现上通常是:

  1. 下单时 :截止时间 = 当前时间 + 15 分钟,写入 lock_until / pay_deadline
  2. 后台定时任务 :每隔一段时间(如 30 秒)扫描
    • 待支付且已过 pay_deadline → 订单超时取消,座位释放
    • 座位仍锁定且已过 lock_until → 释放座位

注意区分两个配置:

配置 含义
15 分钟 业务有效期(锁多久、要在多久内支付)
30 秒 清理任务多久跑一次

清理函数往往不再接收 15,因为截止时间已经落库;它只比较「现在」和「库里的绝对时间」。

这也解释了:把配置从 15 改成 5,一般只影响之后新下的单,已经写下的截止时间不会自动变。


五、座位状态流转

常见三态:

复制代码
空闲 ──下单──▶ 锁定 ──支付──▶ 已售
  ▲              │
  └────取消/超时─┘
相关推荐
FungLeo6 小时前
成为全栈·React 管理后台篇·总复盘:从“接口能调通”到“后台值得使用”
前端·react.js·前端框架·项目复盘·成为全栈
EatFan6 小时前
Spring Boot 4 落地观察:从 yudao-cloud、matecloud、JPower 看国产脚手架的升级路线与迁移清单
java·spring boot·后端·spring cloud·微服务·后端开发·jdk 21
Csvn7 小时前
并发模式:让渲染学会排队、插队和让路
前端
可乐鸡翅yeah_7 小时前
新手梳理:M3U8 线上问题,哪些是前端锅,哪些是后端锅
前端·ios·音视频·实时音视频·m3u8·音视频在线播放
Flynt7 小时前
Linear 用 1000 个 PR 换掉 styled-components,我写了 200 个按钮,把这笔账复现了一遍
前端·css·preact
波力海苔夹心脆6757 小时前
C# 序列化与反序列化详解:System.Text.Json、Newtonsoft.Json、XmlSerializer 用法、特性选项与安全实践
经验分享·后端·c#·json·.net
JavaGuide8 小时前
NVIDIA 又开源了!这次给 AI Agent 加上权限管控
前端·后端
excel8 小时前
prisma 如何处理数据库竞态
前端·数据库·后端
莪_幻尘10 小时前
Skill 体检:30 个 Skill 全凭感觉?体检器先自曝了 8 个“假 0 分
前端·人工智能·llm