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

Web应用并发问题规避:学生订房超订场景下事务与synchronized使用疑问

学生订房系统超订并发问题处理方案

核心疑问解答

不需要把数据库事务代码放到synchronized同步块中,原因如下:

  • synchronized是JVM进程内的线程锁,仅对单个服务实例的线程有效,如果你部署了多台应用实例,跨实例的并发请求完全不受这个锁限制,依然会出现超订问题
  • 即使是单实例部署,synchronized会大幅降低预订接口的并发吞吐量,完全没有必要使用

超订问题具体解决方案

仅开启数据库事务不足以解决超订问题,默认的事务隔离级别无法避免并发修改带来的数据不一致,需要搭配以下方案实现:

方案1:数据库乐观锁(最推荐,性能最优)

适合并发量较高的场景,实现成本极低:

  • 给房间信息表新增version版本号字段,或者直接用剩余可预订数量做校验条件
  • 执行预订扣减库存的SQL时增加校验逻辑,示例SQL如下:
UPDATE room 
SET available_count = available_count - 1, version = version + 1
WHERE room_id = ? AND available_count > 0 AND version = ?
  • 执行更新后如果数据库返回的影响行数为0,说明当前房间已被其他用户预订,直接返回预订失败即可
  • 整个逻辑仅需要搭配READ COMMITTED及以上隔离级别的事务即可运行

方案2:数据库悲观锁(适合并发量较低的场景)

实现简单,不需要额外加字段:

  • 查询房间信息时直接加行级锁,避免其他事务同时修改,示例SQL如下:
SELECT * FROM room WHERE room_id = ? FOR UPDATE
  • 该语句会在事务存续期间锁定对应房间的行记录,其他事务要修改这条数据必须等当前事务提交或回滚,不会出现并发修改冲突
  • 注意要控制事务的粒度,不要在事务中执行过多无关逻辑导致锁持有时间过长,影响整体性能

方案3:分布式锁(适合预订流程包含多步复杂业务的场景)

如果预订流程除了操作房间库存,还有扣减用户积分、发送预订通知等多步关联操作,可以用分布式锁做全局控制:

  • 进入预订流程前,基于房间ID加分布式锁(可通过Redis SETNX、Redisson等实现)
  • 锁的过期时间要设置为大于预订流程的最长耗时,避免锁提前失效导致冲突
  • 执行完全部预订逻辑后释放锁即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 03:36:04