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。

相关推荐
【JAVA】玩家13 分钟前
Spring核心原理全解析:从零到生产实战
java·后端·spring
Wang's Blog40 分钟前
Java框架 SpringCloud 快速入门: 实现 Feign 最佳实践(抽取方式)
java·spring cloud
辻弋2011 小时前
五年前的旅行视频糊成马赛克?Video2X用Real-ESRGAN逐帧重建细节,但只支持Windows、集显用户建议直接放弃
服务器·数据库·windows·游戏引擎·电脑
MandalaO_O1 小时前
IDEA 开发(快捷键 + 调试 + 序列化)
java·ide·intellij-idea
可乐鸡翅yeah_2 小时前
业务中 M3U8 水印相关坑,硬水印和动态水印区别
前端·网络·数据库·ffmpeg·m3u8在线
xiaoqiMikko2 小时前
JVM 线上排查实战(七):jps 看不见它、jstack 连不上它,可它明明活得好好的
java·jvm
石头麻辣鱼2 小时前
Bamboo 调度系统 OceanBase 适配实战:存储过程迁移踩过的三个大坑
数据库
龙亘川3 小时前
数智驱动民政升级 精准守护民生保障
大数据·数据库·人工智能
狼爷3 小时前
Rust/Go/Java/Python/PHP 大比拼:负载下后端框架到底差多少?
java·后端·编程语言
念何架构之路3 小时前
zap扩展生态与总结
java·前端·数据库