【Redis】实现购物秒杀及分布式锁

news2024/12/23 0:38:09

Redis实现购物秒杀及分布式锁

全局唯一ID

Redis自增ID策略

ID构造是:时间戳 + 计数器

每天一个key,方便统计订单量

业务实现

获取指定时间的秒数

LocalDateTime timeBegin = LocalDateTime.of(2024, 1, 1, 0, 0, 0);
long second = timeBegin.toEpochSecond(ZoneOffset.UTC);

获取当前时间的秒数

long now = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);

全局唯一ID业务代码

public Long getID(String key) {
   
    // 获取时间戳
    long now = LocalDateTime.now().toEpochSecond(ZoneOffset.UTC);
    long timestamp = now - TIMESTAMP_BEGIN;

    // 利用redis实现自增长
    String date = new SimpleDateFormat("yyyyMMdd").format(new Date());
    Long inc = redisTemplate.opsForValue().increment("ID:" + key + ":" + date);

    // 拼接并返回
    return timestamp << 32 | inc;
}

实现秒杀下单

秒杀下单逻辑流程

业务实现

存在
不存在
充足
不足
begin
判断库存
判断存在
end
提交商品id
返回异常
扣减库存
创建订单
返回订单id
@Transactional
public String getProduct(Long id) {
   
    // 判断商品是否存在
    Product pro = getById(id);
    if (pro == null) {
   
        throw new BusinessException(400, "商品不存在");
    }
    // 判断库存
    int num = pro.getNum();
    if (num <= 0) {
   
        throw new BusinessException(400, "库存不足");
    }
    // 库存 - 1
    pro.setNum(num - 1);
    update(pro, new QueryWrapper<>());
    
    // 下订单
    Ordertable order = new Ordertable();
    order.setOrderID(idUtil.getID("order").toString());
    order.setUserID(123);
    ordertableService.save(order);
    return order.getOrderID();
}

“超卖”问题

问题复现

在多线程并发会产生问题

使用5000个线程进行测试

20个库存卖了210个订单

原因分析

锁的类型

超卖问题是典型的多线程安全问题,针对这一问题的常见解决方案就是加锁

悲观锁:认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。

  • 例如Synchronized、Lock都属于悲观锁

乐观锁:认为线程安全问题不一定会发生,因此不加锁,只是在更新数据时去判断有没有其它线程对数据做了修改。

  • 如果没有修改则认为是安全的,自己才更新数据。
  • 如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常。

乐观锁

乐观锁的关键是判断之前查询得到的数据是否有被修改过。(CAS法)

代码实现

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1422399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之DatePicker组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之DatePicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、DatePicker组件 日期选择器组件&#xff0c;用于根据指定日期范围创建日期滑…

前端工程\模块化

前端工程\模块化&#x1f3ed; 本篇文章&#xff0c;学习记录于&#xff1a;尚硅谷&#x1f3a2;&#xff0c;紧接前文&#xff1a;邂逅Node.JS的那一夜→博客 无论是前端、后端、甚至非编程领域都有模块化的概念&#xff0c;只是不同的领域叫法不同&#xff0c;不过&#xf…

n-皇后-dfs

import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.OutputStreamWriter; import java.util.Scanner;public class Main {static int n,N 20; //这里只会用到2 * n - 1的格子,开大点保险static char[][] g new c…

编曲学习:功能和声 歌曲结构 和弦编配(上)

34届三和弦 功能和声 歌曲结构 和弦编配&#xff08;上&#xff09;https://app8epdhy0u9502.pc.xiaoe-tech.com/live_pc/l_65b4e014e4b064a83b8f44fd?course_idcourse_2XLKtQnQx9GrQHac7OPmHD9tqbv 34届独立音乐人编曲训练营https://app8epdhy0u9502.pc.xiaoe-tech.com/p/t_…

【Java程序设计】【C00219】基于SSM的大学生课程管理系统(论文+PPT)

基于SSM的大学生课程管理系统&#xff08;论文PPT&#xff09; 项目简介项目获取开发环境项目技术运行截图 项目简介 这个一个基于SSM的大学生课程管理系统&#xff0c;本系统共分为三种权限&#xff1a;管理员、教师和学生 管理员&#xff1a;查看个人中心、学生管理、公告信…

CTF-WEB的知识体系

CTF概念 CTF是Capture The Flag的缩写&#xff0c;中文一般译作夺旗赛 CTF起源于1996年DEFCON全球黑客大会 DEFCONCTF是全球技术水平和影响力最高的CTF竞赛 竞赛模式 解题模式:解决网络安全技术挑战(即找到flag)&#xff0c;提交后获取相应分值。 攻防赛模式:要求找到其他队…

计算机基础知识讲解(原码反码补码)(以及在C语言里面是如何计算和运用的)

补码反码掩码以及原理 补码、反码和掩码是计算机科学中用于表示和处理数值的三种编码方式。 原码 原码是最直观的数值表示方法&#xff0c;它将数值的二进制表示与其符号位结合起来。在原码表示中&#xff0c;正数的符号位为0&#xff0c;而负数的符号位为1。原码的缺点在于…

Django实例_后台管理及分页器

原理步骤参考: Django开发_14_后台管理及分页器-CSDN博客 一、创建Django项目 二、创建page_app python manage.py startapp page_app三、修改settings.py文件 (一)添加app (二)设置每页显示数据个数 (三)设置中文显示 四、总路由添加子路由路径 from django.contrib impo…

MD5算法:高效安全的数据完整性保障

摘要&#xff1a;在数字世界中&#xff0c;确保数据完整性和安全性至关重要。消息摘要算法就是一种用于实现这一目标的常用技术。其中&#xff0c;Message Digest Algorithm 5&#xff08;MD5&#xff09;算法因其高效性和安全性而受到广泛关注。本文将详细介绍MD5算法的优缺点…

C++初阶:入门泛型编程(函数模板和类模板)

大致介绍了一下C/C内存管理、new与delete后&#xff1a;C初阶&#xff1a;C/C内存管理、new与delete详解 我们接下来终于进入了模版的学习了&#xff0c;今天就先来入门泛型编程 文章目录 1.泛型编程2.函数模版2.1概念2.2格式2.3函数模版的原理2.4函数模版的实例化2.4.1隐式实例…

leetcode 27.移除元素(python版)

需求 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺序可以改变。你不需要考虑数组中超出新长度…

Cocos creator 动作系统

动作系统简介 是用于控制物体运动的一套系统&#xff0c;完全依赖代码进行实现&#xff0c;动态调节节点的移动。 移动 cc.moveTo 移动到某个坐标&#xff08;x,y&#xff09; //1秒时间内&#xff0c;移动到0,0let action1 cc.moveTo(1,0,0)this.node.runAction(action1)c…

LeetCode.2670. 找出不同元素数目差数组

题目 题目链接 分析 一种暴力的方法&#xff0c;枚举数组所有数字&#xff0c;分别计算当前元素前面不同的元素和后面不同的元素&#xff0c;然后相减即可。这样的话太暴力&#xff0c;前缀和后缀也需要分别遍历&#xff1a;O(N*2)了。 我们来优化一下&#xff1a; 根据这种…

Git 介绍 与 配置

Git 介绍 Git是一个分布式版本控制系统&#xff0c;用于跟踪文件的更改和协作开发。它可以管理项目的版本历史记录&#xff0c;并允许多个开发者在同一时间进行并行开发。 解决上图产生的问题就出现了git 分布式版本控制系统 看下图 Git 配置 Git的基本配置包括用户名和电子邮…

基于深度学习的鸟类识别系统matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 4.1 卷积神经网络基础 4.2 GoogLeNet模型 4.3 鸟类识别系统 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................…

使用Neo4j做技术血缘管理

目录 一、neo4j介绍 二、windows安装启动neo4j 2.1下载neo4j 2.2 解压文件 2.3 启动neo4j 三、neo4j基础操作 3.1 创建结点和关系 3.2 查询 3.3 更改 3.4 删除 四、技术血缘Demo实现 4.1 构建节点对象 4.2 构建存储对象 4.3 创建有属性关联关系 4.4 最后是图结果…

工业物联网接入网关在制造企业的实际应用-天拓四方

随着工业4.0和智能制造的兴起&#xff0c;工业物联网&#xff08;IIoT&#xff09;已成为工厂自动化的关键驱动力。在这个转变中&#xff0c;工业物联网网关扮演着至关重要的角色。它们充当了设备与企业系统之间的桥梁&#xff0c;实现了数据采集、分析和设备控制等功能。 案例…

微信开放平台第三方开发,实现代小程序认证申请

大家好&#xff0c;我是小悟 微信小程序认证整体流程总共分为五个环节&#xff1a;认证信息填写、平台初审、管理员验证、供应商审核和认证成功。 服务商可以代小程序发起认证申请。平台将对认证基础信息进行初步校验。通过后&#xff0c;平台将向管理员微信下发模板消息&…

实习日志8

1.捷通打印机 1.1.驱动问题&#xff08;不支持RFID设置&#xff09; 换一个驱动&#xff0c;报另一个错 找技术人员对接&#xff0c;换了个新驱动 查看端口 安装驱动&#xff08;选择USB002&#xff09; 1.2.rfid校验不准问题&#xff08;纸张有空白&#xff09; rfid未校验没…

数据库MySQL查询设计||给定四个关联表,其定义和数据加载如下:-- 学生表 Student-- 选课表 SC

SQL查询设计 给定四个关联表&#xff0c;其定义和数据加载如下&#xff1a; -- 学生表 Student create table Student(Sno varchar(6), Sname varchar(10), Sdate datetime, Ssex varchar(10)); insert into Student values(01 , 赵雷 , 1999-01-01 , 男); insert into St…