redis--008

一、秒杀下单基础流程

  1. 接收优惠券 id
  2. 查询优惠券信息
  3. 校验:秒杀时间是否合法(未开始 / 已结束直接返回失败)
  4. 判断库存是否充足,库存不足直接返回失败
  5. 扣减库存
  6. 创建优惠券订单,返回订单 ID

问题:查询库存、扣减库存分为两步操作,高并发多线程场景下出现超卖,属于线程安全问题

二、悲观锁 vs 乐观锁

表格

悲观锁 乐观锁
核心思想 认定并发冲突一定会发生,操作数据前先上锁,线程串行执行 认定冲突不一定发生,不加锁,更新的时候检测是否被别人修改过
实现例子 synchronized、Lock、数据库行锁 版本号法、CAS 法
优点 逻辑简单,保证一定成功 并发性能好,没有锁阻塞
缺点 并发串行,性能较差 高并发场景更新成功率低,可能需要重试

1. 悲观锁

提前获取锁,同一时刻只允许一个线程操作库存,其他线程阻塞等待。 适合写冲突频繁的业务。

2. 乐观锁

不上锁,执行更新时校验数据是否被其他线程改动;如果已经被修改,则更新失败,可以选择重试或者返回报错。 两种实现方式:

  1. 版本号法 数据表增加version版本字段。
  • 查询:同时读出库存 + version
  • 更新:update ... set stock=stock‑1,version=version+1 where id=? and version=旧版本号
  • 如果 where 条件不匹配,说明别的线程已经修改过这条数据,本次扣减失败。
  1. CAS 法(基于库存本身做校验) 不需要额外增加 version 字段,直接拿查询出来的库存值作为条件。
  • 查询得到 stock
  • 更新:update ... set stock = stock‑1 where id=? and stock=查询出来的旧库存
  • 如果条件不命中,代表库存已经被其他线程修改,扣减失败。

CAS 缺点:ABA 问题;版本号法可以规避 ABA。

相关推荐
wear工程师1 小时前
线程池队列满了会怎样?从拒绝策略看懂 ThreadPoolExecutor 的扩容顺序
java
晓晓_za8986681 小时前
多租户 GEO 优化系统源码架构:权限隔离与数据分离实现
java·tcp/ip·spring·缓存·微服务·架构
AI行业应用研究1 小时前
2026年主流报名工具测评报告:眨眼猫会务智能体报名小程序为何成为多场景首选?
java·开发语言·小程序
cxoptics1 小时前
C-Lens在光模块(800G/1.6T)中的应用
java
烬羽1 小时前
一个博客系统,为什么要拆成 6 张表?
数据库·mysql
liangbo71 小时前
JVM规范第 1章:从一段历史到「JVM 并不认识 Java」
java·jvm
程序员-Benothing1 小时前
MySQL 中的日志类型有哪些?binlog、redo log 和 undo log 的作用和区别是什么?
数据库·mysql
XuCoder1 小时前
你写的每条 SQL 都没加过锁,可 MySQL 凭什么不怕两个事务打架?
数据库·后端
TechExplorer3651 小时前
Tomcat 下载与安装
java·tomcat