mysql 防止库存超卖,有哪些方案?

  • MySQL 防止库存超卖的方案分析

    在电商等高并发场景下,防止库存超卖是一个常见问题。以下是几种常见的解决方案及其优缺点分析:

    1. 悲观锁 (FOR UPDATE)

    BEGIN; 
    SELECT stock FROM products WHERE id = 123 FOR UPDATE; -- 检查库存是否足够 
    UPDATE products SET stock = stock - 1 WHERE id = 123; 
    COMMIT;

    优点

    • 实现简单直接
    • 保证强一致性,不会出现并发问题
    • 适合库存量少、竞争激烈的场景

    缺点

    • 性能较差,高并发下容易成为瓶颈
    • 可能导致死锁
    • 锁粒度大,影响系统吞吐量

    2. 乐观锁 (版本号或时间戳)

    UPDATE products SET stock = stock - 1, version = version + 1 
    WHERE id = 123 
    AND version = #{oldVersion} 
    AND stock > 0;

    优点

    • 无锁设计,性能较好
    • 适合读多写少的场景
    • 减少数据库锁竞争

    缺点

    • 实现相对复杂
    • 高并发下失败率高,需要重试机制
    • 不保证每次请求都能成功

    3. 直接库存检查 (库存>0)

    UPDATE products SET stock = stock - 1 
    WHERE id = 123 AND stock > 0;

    优点

    • 实现最简单
    • 性能较好
    • 不需要额外字段

    缺点

    • 在极高并发下仍可能出现超卖(虽然概率低)
    • 无法区分具体失败原因

    4. 其他方案

    4.1 Redis原子操作 + 异步同步

    • 使用Redis的DECR等原子操作
    • 异步同步到数据库
    • 适合秒杀等极端高并发场景

    4.2 预扣库存

    • 下单时预扣库存
    • 支付成功时实际扣减
    • 支付超时回滚库存

    方案对比

    方案 一致性 性能 实现复杂度 适用场景
    悲观锁 简单 库存少,强一致要求
    乐观锁 最终 中等 读多写少,可接受失败
    直接检查 较强 简单 一般电商场景
    Redis 最终 极高 复杂 秒杀等高并发

    推荐方案

    1. 普通电商场景:直接使用 UPDATE ... WHERE stock > 0 通常足够
    2. 高并发秒杀:Redis原子操作 + 异步同步 + 乐观锁
    3. 强一致性要求:悲观锁(但要控制锁持有时间)
    4. 分布式系统:考虑分布式锁或分库分表策略

  • MySQL 并发执行 UPDATE stock > 0 的详细过程分析

    您提出了一个很好的问题:当事务A执行扣减后,事务B执行时库存已经为0,为什么stock > 0条件还能满足?让我们深入分析MySQL的执行机制。

    1. MySQL的UPDATE语句执行流程

    当执行UPDATE products SET stock = stock - 1 WHERE id = 12

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值