优惠券秒杀(三)

这篇具有很好参考价值的文章主要介绍了优惠券秒杀(三)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

优惠券秒杀一人一单

优惠券的目的是为了引流,但是目前的情况是一个人可以无限制的抢这个优惠券,因此,代码中应该添加一个用户只能下一单的逻辑。保证一个用户只能抢一张券,则只要保证该用户下的优惠券只要一张,即根据优惠卷id和用户id查询是否已经下过这个订单,如果能够查询到结果,则表明下过该订单,不能再次下单,否则表示没有下过单,进行下单操作。

优惠券秒杀(三),java
一人一单

存在问题:实现一人一单时,也存在线程安全问题,当多个线程携带的同一个用户id和同一个优惠券id时,此时该用户还没获取过该优惠券,则可能出现多线程问题,多个线程通过用户ID和优惠券ID可能查询不到订单,所以会有多个线程能够下单成功。

乐观锁适合更新数据,现在需要时插入数据,所有我们需要使用悲观锁操作。

@Override
public Long seckillVoucher(Long voucherId) {
    // 查询秒杀优惠券信息
    SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);
    //判断秒杀是否开始和结束
    LocalDateTime beginTime = seckillVoucher.getBeginTime();
    LocalDateTime endTime = seckillVoucher.getEndTime();
    //如果当前时间 在开始时间之后 再结束时间之前 则表明秒杀能进行
    LocalDateTime localDateTime = LocalDateTime.now();
    if ( localDateTime.isBefore(beginTime) || localDateTime.isAfter(endTime) ){
        return null;
    }
    //获取库存量
    Integer stock = seckillVoucher.getStock();
    if (ObjectUtil.isNull(stock) || ObjectUtil.isNotNull(stock) && stock.intValue() <= 0){
        return null;
    }
    Long voucherOrder = createVoucherOrder(voucherId);
    return voucherOrder;
}

@Transactional
public synchronized Long createVoucherOrder(Long voucherId) {
    // 根据用户ID和优惠券ID 判断订单是否存在
    //获取用户ID
    Long id = UserHolder.getUser().getId();

    int count = this.count(new LambdaQueryWrapper<VoucherOrder>().eq(VoucherOrder::getUserId, id).eq(VoucherOrder::getVoucherId, voucherId));
    // 订单已经存在
    if (count > 0){
        return null;
    }

    //扣减库存 将现在库存和之前查询的库存做对比,如果一样,则表明没有人在此中间修改过库存,则认定线程安全,扣除库存
    boolean update = seckillVoucherService.update(
            new LambdaUpdateWrapper<SeckillVoucher>().setSql("stock = stock - 1").eq(SeckillVoucher::getVoucherId, voucherId)
                    .gt(SeckillVoucher::getStock, 0)
    );
    if (!update){
        return null;
    }
    //创建订单
    VoucherOrder voucherOrder = new VoucherOrder();
    //创建订单ID
    long orderId = redisIdWorker.nextId("order");
    voucherOrder.setId(orderId);

    voucherOrder.setUserId(id);
    // 代金券id
    voucherOrder.setVoucherId(voucherId);
    this.save(voucherOrder);
    return orderId;
}
  • 对悲观锁进行优化

    @Override
    public Long seckillVoucher(Long voucherId) {
        // 查询秒杀优惠券信息
        SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);
        //判断秒杀是否开始和结束
        LocalDateTime beginTime = seckillVoucher.getBeginTime();
        LocalDateTime endTime = seckillVoucher.getEndTime();
        //如果当前时间 在开始时间之后 再结束时间之前 则表明秒杀能进行
        LocalDateTime localDateTime = LocalDateTime.now();
        if ( localDateTime.isBefore(beginTime) || localDateTime.isAfter(endTime) ){
            return null;
        }
        //获取库存量
        Integer stock = seckillVoucher.getStock();
        if (ObjectUtil.isNull(stock) || ObjectUtil.isNotNull(stock) && stock.intValue() <= 0){
            return null;
        }
        Long id = UserHolder.getUser().getId();

        synchronized (id.toString().intern()){
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            return proxy.createVoucherOrder(id, voucherId);
        }
    }

    @Override
    @Transactional
    public  Long createVoucherOrder(Long userId, Long voucherId) {
        // 根据用户ID和优惠券ID 判断订单是否存在
        int count = this.count(new LambdaQueryWrapper<VoucherOrder>().eq(VoucherOrder::getUserId, userId).eq(VoucherOrder::getVoucherId, voucherId));
        // 订单已经存在
        if (count > 0){
            return null;
        }
        //扣减库存 将现在库存和之前查询的库存做对比,如果一样,则表明没有人在此中间修改过库存,则认定线程安全,扣除库存
        boolean update = seckillVoucherService.update(
                new LambdaUpdateWrapper<SeckillVoucher>().setSql("stock = stock - 1").eq(SeckillVoucher::getVoucherId, voucherId)
                        .gt(SeckillVoucher::getStock, 0)
        );
        if (!update){
            return null;
        }
        //创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        //创建订单ID
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);

        voucherOrder.setUserId(userId);
        // 代金券id
        voucherOrder.setVoucherId(voucherId);
        this.save(voucherOrder);
        return orderId;
    }
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
    </dependency>
    
    @EnableAspectJAutoProxy(exposeProxy = true)
    @MapperScan("com.hmdp.mapper")
    @SpringBootApplication
    public class HmDianPingApplication {

        public static void main(String[] args) {
            SpringApplication.run(HmDianPingApplication.classargs);
        }

    }

本文由 mdnice 多平台发布文章来源地址https://www.toymoban.com/news/detail-614611.html

到了这里,关于优惠券秒杀(三)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【java爬虫】将优惠券数据存入数据库排序查询

    本文是在之前两篇文章的基础上进行写作的 (1条消息) 【java爬虫】使用selenium爬取优惠券_haohulala的博客-CSDN博客 (1条消息) 【java爬虫】使用selenium获取某宝联盟淘口令_haohulala的博客-CSDN博客  前两篇文章介绍了如何获取优惠券的基础信息,本文将获取到的基本信息存到数据库中

    2024年02月16日
    浏览(53)
  • 智慧影院--java开源电影票优惠券制作系统快速开发

    搭建一个智慧影院可以通过使用Java开源电影票优惠券制作系统来快速开发。这个系统可以帮助影院管理电影票的销售和优惠活动,提供便捷的购票方式和优惠券的生成与使用功能。 首先,我们需要建立一个数据库来存储电影、影厅、放映计划、订单等信息。在数据库中,我

    2024年02月13日
    浏览(71)
  • 微信小程序实现一些优惠券/卡券

    👏 前几周有小伙伴问我如何用css实现一些优惠券/卡券,今天就来分享一波吧!速速来Get吧~ 🥇文末分享源代码。记得点赞+关注+收藏! 2.1 实现内凹圆角 假设我们要实现这样的一个效果,两侧透明内圆角+外侧投影,有几种实现方式呢? 2.1.1 方法一:半圆伪元素(投影不准确

    2024年02月09日
    浏览(41)
  • 小程序中如何核销订单和优惠券

    小程序已成为许多商家线上线下开展业务的重要渠道。客户在小程序中下单/领券后,可能需要商家现场扫码核销,例如超市购物、卖票、游乐园等线下场景。下面就介绍小程序中如何核销订单和优惠券。 一、订单核销 订单核销是指商家在小程序中确认顾客已经支付的订单并

    2024年03月21日
    浏览(47)
  • 机器学习:基于逻辑回归对优惠券使用情况预测分析

    作者:i阿极 作者简介:Python领域新星作者、多项比赛获奖者:博主个人首页 😊😊😊如果觉得文章不错或能帮助到你学习,可以点赞👍收藏📁评论📒+关注哦!👍👍👍 📜📜📜如果有小伙伴需要数据集和学习交流,文章下方有交流学习区!一起学习进步!💪 订阅专栏案

    2024年02月02日
    浏览(44)
  • 两天撸一个优惠券小程序,记录下开发的小小经验

    下载微信开发者工具😃😃 新建项目文件夹project,比如 D:workProjectproject 在project下创建src目录放微信小程序的源码,.gitignore文件是用来git上传gitee上忽略一些文件用的,另外三个js文件时用来混淆小程序源码的脚本,将脚本和小程序源码分开是为了脚本更好处理混淆过程。

    2023年04月08日
    浏览(55)
  • 【实践篇】教你玩转JWT认证---从一个优惠券聊起

    最近面试过程中,无意中跟候选人聊到了JWT相关的东西,也就联想到我自己关于JWT落地过的那些项目。 关于JWT,可以说是分布式系统下的一个利器,我在我的很多项目实践中,认证系统的第一选择都是JWT。它的优势会让你欲罢不能,就像你领优惠券一样。 大家回忆一下一个

    2024年02月05日
    浏览(43)
  • 淘宝APP商品详情接口(商品信息,价格销量,优惠券信息,详情图等)

    淘宝APP商品详情接口(商品信息接口,价格销量接口,优惠券信息接口,详情图接口等)代码对接如下: 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以GET方式拼接在URL中),点击获取请key和secret secret String 是 调用密钥 api_name String 是 API接口名称(包括在请求地址

    2024年02月12日
    浏览(51)
  • 业务安全情报第16期 | 大促8成优惠券竟被“羊毛党”抢走!?

    近期,某电商小程序举办美食节营销活动,提供高额折扣券,并允许用户进行秒杀。然而,羊毛党团伙利用作弊手段,抢购囤券,然后倒卖变现,严重损害了商家的利益。 根据顶象防御云编号为BSI-2023-rutq业务安全情报发现,某电商平台为吸引人气和促进销售推,推出高额折

    2024年02月07日
    浏览(49)
  • 斐讯1200M四天线双频路由器PSG1208只要88元 快来领取优惠券

    斐讯斐赛克斯专卖店针对1200M斐讯PSG1208无线路由器启动淘抢购活动,现价88元(原价98元),其拥有1200M传输速率、2.4G/5.8G双频并发、WISP中继等特性。 立刻下单 。 斐讯PSG1208使用802.11ac协议,2.4G/5.8G双频并发,数据传输速率达1167Mbps;配以联发科SOC MT7620A处理器、4天线4*4MIMO架构

    2024年02月08日
    浏览(62)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包