首页 > 其他分享 >使用乐观锁和CAS解决超卖(Overselling)

使用乐观锁和CAS解决超卖(Overselling)

时间:2024-06-13 22:59:07浏览次数:18  
标签:Result CAS Overselling voucher 超卖 id stock

今天我要和大家分享的是如何在Java中使用乐观锁和CAS(Compare-And-Swap)技术来解决超卖的问题。最近我在项目中实现了这个功能,觉得非常有意思,所以决定分享出来。希望对大家有所帮助!

背景介绍

秒杀活动通常在电商平台中很常见,我觉得实现这个功能的难点在于多线程避免超卖。为了应对这个问题,我们使用了乐观锁和CAS法,这样也不至于像悲观锁一样串行,而且兼顾了高并发的性能。

@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {

    @Resource
    private ISeckillVoucherService seckillVoucherService;

    @Resource
    private RedisIdWorker redisIdWorker;

    @Override
    @Transactional
    public Result seckillVoucher(Long voucherId) {
        // 1.查询优惠券
        SeckillVoucher voucher = seckillVoucherService.getById(voucherId);
        // 2.判断秒杀是否开始
        if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {
            // 尚未开始
            return Result.fail("秒杀尚未开始!");
        }
        // 3.判断秒杀是否已经结束
        if (voucher.getEndTime().isBefore(LocalDateTime.now())) {
            // 已经结束
            return Result.fail("秒杀已经结束!");
        }
        // 4.判断库存是否充足
        if (voucher.getStock() < 1) {
            // 库存不足
            return Result.fail("库存不足!");
        }
        // 5.扣减库存 - 使用乐观锁和CAS
        boolean success = seckillVoucherService.update()
                .setSql("stock = stock - 1")
                .eq("voucher_id", voucherId)
                .gt("stock", 0)  // 防止超卖
                .update();
        if (!success) {
            // 扣减库存失败
            return Result.fail("库存不足!");
        }
        // 6.创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        // 6.1.设置订单id
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);
        // 6.2.设置用户id
        Long id = UserHolder.getUser().getId();
        voucherOrder.setUserId(id);
        // 6.3.设置优惠券id
        voucherOrder.setVoucherId(voucherId);
        save(voucherOrder);
        // 7.返回订单id
        return Result.ok(orderId);
    }
}

用乐观锁和CAS扣减库存:这里使用了MyBatis Plus的update方法,通过设置setSql("stock = stock - 1")和条件eq("voucher_id", voucherId)gt("stock", 0)来确保在扣减库存时不会发生超卖。CAS确保了操作的原子性,这让并发情况下库存扣减的操作更加可靠。

最后通过Jmeter测试,异常率为0

标签:Result,CAS,Overselling,voucher,超卖,id,stock
From: https://blog.csdn.net/Takumilove/article/details/139621838

相关文章

  • 龙哥量化:通达信新超买超卖指标公式源码
    如果您需要代写公式,请联系我。龙哥QQ:591438821龙哥微信:Long622889新超买超卖指标公式使用说明:1.适用于超跌反弹行情。2.个股大幅下跌后,连续出现黄区块表明进入超卖严重,一段时间内出现的次数越多连续时间越长,后面的行情越有期待。3.当出现买入信号,可以试探性的入场,同时设定......
  • 一步步了解C++类型转换:static_cast、const_cast、reinterpret_cast和dynamic_cast
    1. static_caststatic_cast 可以用于基础类型之间的转换,类层次结构中的父类和子类之间的转换,以及把 void* 转换成目标类型的指针等。静态类型转换示例:#include<iostream>classBase{};classDerived:publicBase{};intmain(){//基础数据类型int......
  • 南方CASS 10.1安装教程附安装包下载
    南方CASS10.1是一个非常好的专业测量工具,主要是由南方测绘仪器公司AutoCAD2000上开发的新一代数字化地形地籍成图软件。其主要特色是面向GIS,彻底打通了数字化成图系统与GIS的接口。对于这一特色的主要支撑技术包括在属性编码基础上进一步研究开发的骨架线实时编辑、简码用户......
  • 2024年农业科学与可持续发展国际会议(ICASSD2024)
    2024年农业科学与可持续发展国际会议(ICASSD2024)会议简介2024年国际农业科学与可持续发展大会(ICASSD2024)很高兴邀请您提交主题为“农业科学和可持续发展的当前挑战和未来前景”的原稿。通过ICASSD2024,农业、食品和生物技术三个重要领域的完美融合将为研究人员、农学家、政策......
  • CASIO fx-991CN X 使用
    复数转换\(a+b\,{\mathrmi}\leftrightarrowr\angle\theta\)进入复数运算模式菜单2输入待转换数OPTN⬇️,选择目标格式。=可通过SHIFT设置⬇️2选择默认输出格式角度弧度转换例:将弧度转换为角度在角度模式D下输入待转换的弧度值。(若要转换模式,SHIFT菜单......
  • Case专题--->(28)verilog 优先Case(四)
     (28)verilog优先Case(四)1目录(a)IC简介(b)vim简介(c)Verilog简介(d)verilog优先Case(四)(e)结束1IC简介(a)在IC设计中,设计师使用电路设计工具(如EDA软件)来设计和模拟各种电路,例如逻辑电路、模拟电路、数字信号处理电路等。然后,根据设计电路的规格要求,进行布局设计和布线,确定各......
  • PingCastle 3.2.0.1 - Active Directory 安全检测和评估
    PingCastle3.2.0.1-ActiveDirectory安全检测和评估活动目录域安全分析工具请访问原文链接:https://sysin.org/blog/pingcastle/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org在20%的时间内获得80%的ActiveDirectory安全性ActiveDirectory正迅速成为......
  • mysql order by后跟case when
    在SQL中,ORDERBY子句用于对查询结果进行排序。当在ORDERBY后面使用CASE语句时,它的原理是:根据CASE语句中定义的条件和结果,为查询结果集中的每一行生成一个临时的排序值。然后,根据这些排序值对结果集进行排序。具体来说,CASE语句在ORDERBY中的工作原理如下:   条件判断:CASE......
  • 玩客云刷armbian+CasaOS+Docker+LED灯控制+QBitTorrent+Cpolar内网穿透+青龙+Home Ass
    一、【玩客云的配置介绍】CPU是晶晨S805这是一款32位处理器的CPU,性能放在现在来看是比较弱鸡的,很多玩法都被这颗CPU的性能局限了。双USB2.0这个同样是被吐槽的地方,严重影响文件的传输速度。千兆网口这点比很多同期的设备强。但刷部分固件后会变成百兆。1GB+8GB存储组合这......
  • golang select 的 case 执行顺序
    问题:golangselect结构,假如底下有三个case,分别从chan1,chan2,chan3读取内容,chan1,chan2,chan3都是非阻塞的,那么是会先进入第一个case,其它case还会再进入吗?在Go语言中,select语句用于监控多个通道的操作,并在其中一个操作准备好时执行相应的case。如果多个case同......