Redis实现限量优惠券的秒杀
核心:避免超卖问题,保证一人一单
业务逻辑
代码步骤分析

全部代码
@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {@Resourceprivate ISeckillVoucherService seckillVoucherService;@Resourceprivate RedisIdWorker redisIdWorker;@Resourceprivate StringRedisTemplate stringRedisTemplate;@Resourceprivate RedissonClient redissonClient;@Overridepublic Result seckillVoucher(Long voucherId) {//1 查询优惠券信息SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);//2 判断秒杀是否开始LocalDateTime now = LocalDateTime.now(); //现在时间LocalDateTime beginTime = seckillVoucher.getBeginTime(); //开始时间LocalDateTime endTime = seckillVoucher.getEndTime(); //结束时间if (now.isBefore(beginTime)) {return Result.fail("秒杀还未开始");}//3 判断秒杀是否结束if (now.isAfter(endTime)) {return Result.fail("秒杀已结束");}//4 判断库存是否充足int stock = (int) seckillVoucher.getStock();if (stock == 0 && stock <= 0) {return Result.fail("库存不足");}//确保一人一单 用户ID和代金券ID联合查询Long userId = UserHolder.getUser().getId();//先获取锁 再提交事务//synchronized (userId.toString().intern()) {//创建锁对象//SimpleRedisLock simpleRedisLock = new SimpleRedisLock("order:" + userId, stringRedisTemplate);RLock lock = redissonClient.getLock("lock:order:" + userId);//获取锁boolean isLock = lock.tryLock();//判断是否获取锁成功if (!isLock){//获取锁失败 返回错误或失败return Result.fail("不允许重复下单");}try {//获取事务的代理对象IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();return proxy.creatVoucherOrder(voucherId);} finally {//释放锁lock.unlock();}//}//事务提交之后在释放锁}/*** 这里对于加锁做出一些解释:如果锁加在整个方法上,那么就会导* 致锁的粒度过大,导致每个进程进来都会锁住,所以要控制锁的粒度*/@Transactionalpublic Result creatVoucherOrder(Long voucherId) {Long userId = UserHolder.getUser().getId();Integer count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();if (count > 0) {return Result.fail("用户已经购买过了");}//5 扣减库存-boolean success = seckillVoucherService.update().setSql("stock = stock -1 ") //乐观锁.eq("voucher_id", voucherId).gt("stock", 0) //判断库存是否大于0: where id = ? and stock > 0.update();if (!success) {return Result.fail("库存不足");}//6 创建订单//6.1 订单IDVoucherOrder voucherOrder = new VoucherOrder();long orderid = RedisIdWorker.nextId("order");voucherOrder.setVoucherId(orderid);//6.2 用户IDvoucherOrder.setUserId(userId);//6.3 代金券IDvoucherOrder.setVoucherId(voucherId);save(voucherOrder);//7 返回订单idreturn Result.ok(orderid);}}
相关文章:
Redis实现限量优惠券的秒杀
核心:避免超卖问题,保证一人一单 业务逻辑 代码步骤分析 全部代码 Service public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {Resourceprivate ISeckillVoucher…...
Linux centOS 7 安装 rabbitMQ
1.安装前需要了解,rabbitmq安装需要先安装erlang,特别注意的是erlang与rabbitmq的版本之间需要匹配。 el/7/rabbitmq-server-3.10.0-1.el7.noarch.rpm - rabbitmq/rabbitmq-server packagecloud 3.10版本的rabbitmq 对于erlang的版本要求可以看此连接…...
活着就好20241202
亲爱的朋友们,大家早上好!今天是2024年12月2日,第49周的第一天,也是十二月的第二天,农历甲辰[龙]年十月三十。在这个全新月份的开始、阳光初升的清晨,愿第一缕阳光悄悄探进你的房间,带给你满满的…...
自由学习记录(28)
C# 中的流(Stream) 流(Stream)是用于读取和写入数据的抽象基类。 流表示从数据源读取或向数据源写入数据的矢量过程。 C# 中的流类是从 System.IO.Stream 基类派生的,提供了多种具体实现,每种实现都针对…...
操作系统、虚拟化技术与云原生01
操作系统基础 操作系统定义 OS声明了软件怎么调用硬件,同时支持人机交互 人机交互的过程: shell是人机交互转换的虚拟环境,内核只能识别0、1组成的数据流,底层资源只能识别电流的变化 操作系统的组成 1. 进程管理 进程定义&#x…...
linux的挂卸载
挂卸载操作 在 Linux 系统中,挂载(mount)和卸载(umount)是管理文件系统和存储设备的核心操作。通过这两个操作,我们可以将设备(如硬盘、光盘、U盘等)或网络文件系统的内容集成到系统…...
【和春笋一起学C++】OpenCV中数组和指针运用实例
前言:前面学习了数组和指针在C中的处理原理,本文通过自己编写一个图像处理的函数实例来加深对数组和指针的理解。为什么是图像处理呢,因为图像数据是一个二维矩阵,相当于一个二维数组,前面学习了一维数组,现…...
Maya 中创建游戏角色的头发,并将其导出到 Unreal Engine 5
这段视频教程讲解了如何在 Maya 中创建游戏角色的头发,并将其导出到 Unreal Engine 5 中,重点是如何处理头发的物理模拟和材质。 作者 Andrew Giovannini 首先展示了一个已完成的带物理模拟的头发模型,并介绍了他自己的游戏行业背景。然后&a…...
React 路由(React Router):在 React 应用中管理路由
🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…...
SAP-CPI组件Transformation介绍之Converter
1.配置CSV to XML Converter Field Description XML Schema 选择Select按钮,选择合适 XSD 文件. 或者可以选择 Upload from File System 系统中查找合适的XML文件....
Laravel 代理收益排行榜
创建了一个收入表 CREATE TABLE income_logs (id int(11) unsigned NOT NULL AUTO_INCREMENT,order_id int(11) NOT NULL COMMENT 订单ID,type int(11) NOT NULL DEFAULT 0 COMMENT 类型 0 支出 1收入,user_id int(11) NOT NULL COMMENT 消费者用户,price decimal(10,2) NOT…...
LeetCode hot100面试背诵版(自用)
点击题目可以跳转到LeetCode 哈希 两数之和 public int[] twoSum(int[] nums, int target) {int lengthnums.length;int[] ans new int[2];for (int i 0; i <length-1 ; i) {for (int j i1; j < length; j) {if(nums[i]nums[j]target){ans[0]i;ans[1]j;}}}return an…...
常见的Web安全漏洞——XSS
概念 跨站脚本攻击(XSS),指攻击者通过篡改网页,嵌入恶意脚本程序,在用户浏览网页时,控制用户浏览器进行恶意操作。 XXS的分类 反射型XSS存储型XSSDOM型XSS 原理 反射型XSS 接收用户提交的访问者的姓名࿰…...
liteflow 架构详解
LiteFlow 是一个轻量级的、高性能的流程编排框架,主要用于解决复杂业务流程的编排问题。它提供了一种简单而强大的方式来定义和执行复杂的业务流程。下面是 LiteFlow 的架构详解: 核心概念 组件(Component):是流程中…...
国产麒麟操作系统上运行LabVIEW
LabVIEW 目前并没有官方支持直接在国产麒麟操作系统(Kylin OS)上运行。LabVIEW 是由美国国家仪器公司(NI)开发的软件,主要面向 Windows 和 Linux 操作系统。麒麟操作系统虽然基于 Linux,但其内核和一些软件…...
【C语言】结构体(一)
一,是什么 结构体就是一些值的集合,这些值称为成员变量。 结构体的每个成员可以是不同类型的变量。说到集合,数组也是集合,但是不同的是数组只能是相同类型元素的集合。 二,结构体的声明 struct tag { member1;…...
C++《set与map》
在之前我们已经学习了解了CSTL当中的string和vector等容器,现在我们已经懂得了这些容器提供的接口该如何使用,并且了解了这些容器的底层结构。接下来我们在本篇当中将继续学习STL内的容器set与map,在此这两个容器与我们之前学习的容器提供的成…...
深度学习-52-AI应用实战之基于Yolo8的目标检测自动标注
文章目录 1 YOLOv81.1 YOLOV8的不同版本1.2 可检测类别1.3 数据说明1.4 网络结构1.5 算法核心步骤2 目标检测的基本原理2.1 安装yolov8(cpu版本)2.2 图片检测2.3 视频检测2.4 自动标注2.5 保存标注结果3 参考附录1 YOLOv8 YOLOv8是一种前沿的计算机视觉技术,它基于先前YOLO版…...
【Elasticsearch】05-DSL查询
1. 查询所有 es最多只支持查询1万条数据。 # 查询所有 GET /items/_search {"query": {"match_all": {}} }2. 叶子查询 全文检索 会对结果进行相关度打分。 # 检索单个字段 GET /items/_search {"query": {"match": {"name&…...
qml项目创建的区别
在Qt框架中,你可以使用不同的模板来创建应用程序。你提到的这几个项目类型主要针对的是Qt的不同模块和用户界面技术。下面我将分别解释这些项目类型的区别: 根据你提供的信息,以下是每个项目模板的详细描述和适用场景: Qt Widgets…...
原来湖南2026年的灯光设计趋势竟然是这样的?
原来湖南2026年的灯光设计趋势竟然是这样的?随着科技的不断进步和人们生活水平的提高,灯光设计在家居和商业空间中的重要性日益凸显。湖南作为中部地区的经济大省,其灯光设计趋势也备受关注。本文将深入探讨2026年湖南灯光设计的主要趋势&…...
智慧农业棉花棉铃病害成熟度检测数据集VOC+YOLO格式969张6类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件)图片数量(jpg文件个数):969标注数量(xml文件个数):969标注数量(txt文件个数):969标注类别数&…...
别再只会用`docker system prune`了!聊聊Docker磁盘清理的5个隐藏场景与实战命令
别再只会用docker system prune了!聊聊Docker磁盘清理的5个隐藏场景与实战命令 Docker作为现代开发与运维的核心工具,其便捷性背后往往隐藏着磁盘管理的复杂性。当docker system prune成为大多数人的清理"万能药"时,真正棘手的磁盘…...
开发者在多模型项目中如何利用 Taotoken 进行灵活路由与降级
🚀 告别海外账号与网络限制!稳定直连全球优质大模型,限时半价接入中。 👉 点击领取海量免费额度 开发者在多模型项目中如何利用 Taotoken 进行灵活路由与降级 在构建依赖大模型服务的应用时,服务的连续性与稳定性是开…...
Fortune.js未来路线图:即将推出的功能和改进终极指南
Fortune.js未来路线图:即将推出的功能和改进终极指南 【免费下载链接】fortune Non-native graph database abstraction layer for Node.js and web browsers. 项目地址: https://gitcode.com/gh_mirrors/fo/fortune Fortune.js作为一个创新的非原生图数据库…...
如何快速掌握Vanna AI:新手完整指南从零构建智能数据库查询系统
如何快速掌握Vanna AI:新手完整指南从零构建智能数据库查询系统 【免费下载链接】vanna 🤖 Chat with your SQL database 📊. Accurate Text-to-SQL Generation via LLMs using Agentic Retrieval 🔄. 项目地址: https://gitcod…...
3步搞定TikTok音乐提取:DouK-Downloader终极免费工具使用指南
3步搞定TikTok音乐提取:DouK-Downloader终极免费工具使用指南 【免费下载链接】TikTokDownloader TikTok 发布/喜欢/合辑/直播/视频/图集/音乐;抖音发布/喜欢/收藏/收藏夹/视频/图集/实况/直播/音乐/合集/评论/账号/搜索/热榜数据采集工具/下载工具 项…...
三星固件下载神器Bifrost:跨平台一站式解决方案深度解析
三星固件下载神器Bifrost:跨平台一站式解决方案深度解析 【免费下载链接】Bifrost Cross-platform tool for downloading Samsung mobile device firmware. 项目地址: https://gitcode.com/gh_mirrors/sa/Bifrost Bifrost是一款基于Kotlin Multiplatform构建…...
从原理图到Ping通:我的STM32F407 RMII以太网调试笔记(含LAN8720硬件差异处理)
从原理图到Ping通:我的STM32F407 RMII以太网调试笔记(含LAN8720硬件差异处理) 第一次点亮STM32F407的以太网接口时,那种成就感至今难忘。但在此之前,我经历了整整两周的煎熬——原理图反复检查、PCB打样两次、软件调试…...
基于qstock的北向资金量化分析框架构建与策略应用
基于qstock的北向资金量化分析框架构建与策略应用 【免费下载链接】qstock qstock由“Python金融量化”公众号开发,试图打造成个人量化投研分析包,目前包括数据获取(data)、可视化(plot)、选股(stock)和量化回测(策略b…...
