基于Lua+Redis实现库存的秒杀扣减

电商秒杀场景下,如何用Redis+Lua脚本实现原子性库存扣减(附完整代码) 本文针对电商秒杀场景下的高并发与超卖难题,详细解析了如何利用Redis的原子性命令与Lua脚本实现可靠的库存扣减。通过对比多种方案,阐述了Redis+Lua作为黄金搭档的技术原理,并提供了从基础扣减到预扣减模型的完整代码实现,确保在高并发下数据的一致性与系统性能。 阅读详情

基于Lua+Redis实现库存的秒杀扣减

在库存扣减中,我们一般使用lua脚本来保证原子性

以下是库存和库存流水记录的lua脚本:

KEYS[1] = 库存的 key
KEYS[2] = 流水的 key
ARGV[1] = 本次要扣减的库存数
AGRV[2] = 本次扣减的唯一编号

String luaScript = """
    -- 检查操作是否已经执行过,通过检查哈希表(KEYS[2])中是否存在标识(ARGV[2])
    if redis.call('hexists', KEYS[2], ARGV[2]) == 1 then
        -- 如果存在,返回错误信息'OPERATION_ALREADY_EXECUTED'
        return redis.error_reply('OPERATION_ALREADY_EXECUTED')
    end
    -- 获取当前库存值
    local current = redis.call('get', KEYS[1])
    -- 如果库存键不存在,返回错误信息'KEY_NOT_FOUND'
    if current == false then
        return redis.error_reply('KEY_NOT_FOUND')
    end
    -- 如果当前值不是数字,返回错误信息'current value is not a number'
    if tonumber(current) == nil then
        return redis.error_reply('current value is not a number')
    end
    -- 如果当前库存小于请求的扣减数量,返回错误信息'INVENTORY_NOT_ENOUGH'
    if tonumber(current) < tonumber(ARGV[1]) then
        return redis.error_reply('INVENTORY_NOT_ENOUGH')
    end

    -- 计算新的库存值
    local new = tonumber(current) - tonumber(ARGV[1])
    -- 设置新的库存值
    redis.call('set', KEYS[1], tostring(new))

    -- 获取Redis服务器的当前时间(秒和微秒)
    local time = redis.call("time")
    -- 转换为毫秒级时间戳
    local currentTimeMillis = (time[1] * 1000) + math.floor(time[2] / 1000)
    -- 使用哈希结构存储操作日志
    redis.call('hset', KEYS[2], ARGV[2], cjson.encode({
        action = "decrease",  -- 操作类型:增加
        from = current,       -- 操作前的库存值
        to = new,             -- 操作后的库存值
        change = ARGV[1],     -- 变化量
        by = ARGV[2],         -- 操作标识
        timestamp = currentTimeMillis  -- 操作时间戳
    }))
    -- 返回新的库存值
    return new
""";

JAVA调用



    /**
     * Executes Lua script
     * 
     * @param <R> - type of result  
     * @param mode - execution mode    READ OR WRITE
     * @param luaScript - lua script    lua脚本
     * @param returnType - return type   返回类型
     * @param keys - keys available through KEYS param in script  key集合
     * @param values - values available through VALUES param in script  values参数
     * @return result object
     */
    <R> R eval(Mode mode, String luaScript, ReturnType returnType, List<Object> keys, Object... values);

    @Autowired
    private RedissonClient redissonClient;

Integer result = ((Long) redissonClient.getScript().eval(RScript.Mode.READ_WRITE,
                    luaScript,
                    RScript.ReturnType.INTEGER,
                    Arrays.asList(KEYS[1], KEYS[2]),//KEYS[1], KEYS[2]看具体业务字段
                    ARGV[1],ARGV[2])).intValue();//ARGV[1],ARGV[2]看具体业务字段
Redis使用lua脚本实现库存扣减 Lua 允许您在 Redis 中运行部分应用程序逻辑。这样的脚本可以跨多个键执行条件更新,可能以原子方式组合几种不同的数据类型。 阅读详情

相关推荐

STM32内存大小与地址的对应关系以及计算方法

1、概述 在计算机中要访问存储区,都是通过地址来进行访问的,包括所有的外设(比如串口、内存、硬盘等),都对应有一个访问地址,地址就相当于门牌号,有了门牌号,我们才知道操作的是哪一个区域、哪一个外设。 最被大家熟知的是计算机内存,计算机内存有4G、8G,16G等等,对于程序员而言,要在代码中操作这些内存,肯定得知道内存的地址,此外,还需要会计算地址与内存大小的计算方法与对应关系。STM32作为微

Ace's Blog 4万+

同一热卖商品的高并发写难题 - Lua脚本扣减库存方案

org.springframework.data.redis.core.script.DefaultRedisScript#getSha1获取Lua脚本的校验码,是对Lua脚本的预加载,首次执行生成SHA的校验码,第二次执行无需生成校验码。通常来说,秒杀场景的爆款商品库存数量相对较少,当发生库存扣减操作时,实际上落到数据库中的写流量很小,只要系统上游能够配合交易系统做好限流保护,数据库基本上不会有太大的负载压力,但大库存的限时抢购场景就恰恰相反了。若采用分布式锁,该方案太重,并发量上不去。

爱我所爱0505 1739

【ros2】ros2_control 全面解析与实战指南

ros2_control 是 ROS2 生态中用于机器人实时控制的核心框架,旨在统一硬件接入接口、复用控制算法,避免重复开发,实现仿真与实机硬件的无缝迁移。其核心目标是简化不同硬件(传感器、执行器、完整系统)的集成流程,让开发者专注于控制逻辑而非硬件适配。创建类型功能包,依赖rclcpp。实现on_initupdate在中声明控制器插件,编译生成动态库。在 YAML 配置文件中指定自定义控制器类型,加载测试。

EnHengNa的博客 1475

【实践篇】4.10 Redis使用Lua脚本和Redisson来保证库存扣减中的原子性和一致性

背景:最近有社群技术交流的同学,说面试被问到商品库存扣减的问题。我大概整理了一下内容,方便大家理解。其实无外乎就是分布式锁和Redis命令的原子性问题。在分布式系统中,保证数据的原子性和一致性是一个关键问题。特别是在库存扣减等场景中,确保操作的原子性是至关重要的,以避免数据不一致和并发冲突的问题。为了解决这个挑战,我们可以利用 Redis 数据库的强大功能来实现库存扣减的原子性和一致性。本博客将介绍两个关键技术:Redis Lua脚本和Redisson,它们在库存扣减场景中的应用。

日拱一卒无有尽,功不唐捐终入海 3616

ROS应用之如何配置RTOS满足机器人系统中的实时要求

实时操作系统(RTOS)基本概念实时操作系统(RTOS)是设计用于实时应用的操作系统,其主要目标是在确定的时间内完成任务。RTOS的任务调度算法和优先级控制机制能够确保高优先级任务按时完成。精确的传感器数据采集:传感器数据需要在规定时间内采集并传输给控制系统。快速响应外部事件:对于控制系统,需要确保指令在最短的时间内得到响应。任务的调度周期:任务的周期可以通过公式计算,其中 ftask 是任务的调度频率。优先级分配。

weixin_68094467的博客 1008

20道SpringSecurity常见面试题汇总(超详细回答 !!!)

本文中,我们将探讨一些与 Spring Security 相关的面试问题。Spring Security 是一款流行的 Java 应用程序安全框架,它提供了一套全面且易于使用的安全解决方案。

小斜同学的博客 3076

springboot系列:通过redis+lua脚本实现无锁库存扣减

spingboot结合redis实现库存无锁设计

1091

空天大模型详解

空天大模型是指面向空天信息领域(如卫星遥感、导航、气象等)设计的多模态人工智能模型,能够处理海量遥感数据、多传感器信息及跨时空分析任务。多模态融合:整合可见光、雷达、热红外、多光谱等多源遥感数据,构建统一表征空间,例如“空天·灵眸”3.0版支持航空、卫星及无人机数据的自动化解译。轻量化与高效推理:针对星载计算场景,采用分层量化、跨模态蒸馏技术压缩模型参数(如JigonGPT从1.02B压缩至0.23B,性能仅牺牲5.2%)18,并通过热传导架构提升计算速度2.4倍。神经符号结合。

zxy98的专栏 1567

lua脚本的简单使用!!!

【代码】lua脚本的简单使用!!!

qq_64847107的博客 587

音视频开发基础(1):模拟视频技术简介

模拟视频技术是指用模拟技术对动态影像进行捕捉、记来、处理、存储、传输、复现的技术.模拟视频技术的发明、发展与模拟电视系统的发展密不可分.下面将通过模拟电视系统来介绍模拟视频技术中的基本概念. 首先,人的视觉系统的特征为电视等視稿系铳的发明、发展提供了理论依据.光线通过角膜、腫孔、晶状体的折射光线.透过玻璃体到达视网展.视网膜上分布着光感受器,光感受器在光线的剌激下...

琅嬛福地 1493

基于环形槽谐振器与PIN二极管的频率可重构Vivaldi天线设计与CST仿真研究

摘要 本文设计了一种基于FR4基板的频率可重构Vivaldi天线,通过集成环形槽谐振器(CSRR)和PIN二极管开关实现超宽带(UWB,2-8 GHz)与窄带(2.4/3.5/5.2 GHz)模式的电控切换。天线采用指数渐变槽线结构,结合CSRR的滤波特性和PIN二极管的开关功能,利用CST仿真优化参数。结果表明,UWB模式下S11<-10 dB,窄带模式下目标频点谐振显著,其他频段抑制良好,验证了设计的可行性。该方案为多频段无线通信系统提供了紧凑、低成本的可重构天线解决方案。 关键词:频率可重构天线

huanghm88的专栏 217

使用 Redis + Lua 脚本实现【秒杀库存扣减】

Redis + Lua 实现高并发原子库存扣减 在秒杀等高并发场景下,传统"查询+扣减"两步操作会导致超卖问题。使用Redis的Lua脚本可将这两个操作合并为原子操作: Lua脚本核心逻辑: 检查库存是否>0 原子性执行DECR扣减 返回1(成功)/0(失败) 推荐使用EVALSHA: 先SCRIPT LOAD缓存脚本 通过SHA1摘要高效执行 优势: 完全原子性操作 避免网络往返延迟 相比事务更灵活高效 该方法同样适用于优惠券发放、积分扣减等需要原子操作的场景。

JanelSirry's Blog 1516

深度学习+遥感:2025最新土地利用分类资源大全(数据集/论文/代码)

近年来,深度学习在遥感影像土地利用分类领域取得了突破性进展,从传统的农田、森林识别,到复杂的城市功能区划分,AI正在重新定义我们对地表覆盖的认知。无论是科研还是工程应用,高质量数据集、前沿算法和开源工具都是成功的关键。本文精心整理了2024年最值得关注的土地利用分类资源,包括:✅ 10+个权威数据集(覆盖全球、多分辨率、多光谱/雷达)✅ 15+篇顶会论文(CNN/Transformer/自监督学习等SOTA方法)✅ 6大开源工具箱(PyTorch/Keras实现,即拿即用)

hanfeng5268的博客 1312

简单的秒杀库存扣减逻辑实现(Redis+Lua+Golang)

本文介绍了一个基于Redis + Lua脚本 + Golang(Gin)的秒杀库存扣减系统实现。系统通过Lua脚本确保库存操作的原子性,防止超卖问题。主要功能包括:初始化库存、HTTP接口触发秒杀、并发安全处理等。项目采用清晰的模块化结构,包含Redis客户端封装、服务逻辑、控制器和路由等组件。通过Lua脚本将库存查询和扣减操作合并为一个原子命令执行,解决了传统多命令拼接可能导致的并发问题。

bojinyuan00的博客 872

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

redis+lua脚本实现秒杀扣减库存 & SpringBoot环境+Redisson客户端

redis+lua脚本实现秒杀扣减库存 & SpringBoot环境+Redisson客户端

kerwin的博客 8452

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

基于Redis+Lua实现分布式锁模拟秒杀扣减库存业务

基于Redis+Lua实现分布式锁模拟秒杀扣减库存业务(非常详细,良心解析)

dhklsl的专栏 522

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Redis+Lua脚本实现高并发库存扣减,秒杀系统防超卖实战解析

在高并发场景下,库存扣减的正确性直接关系到业务成败,超卖问题成为电商秒杀系统的核心挑战。原子性操作是解决并发竞态的关键,而Redis单线程模型配合Lua脚本,能够将“判断库存+扣减库存”合并为不可分割的整体,天然规避了分布式锁的复杂性。该方案不仅性能优越,还能灵活扩展限购、批量扣减等复杂业务逻辑,是构建高吞吐、强一致库存服务的理想选择。从技术原理到工程落地,剖析如何借助Redis+Lua实现原子性扣减,结合Spring Boot完整代码与压测验证,为秒杀、抢购等典型场景提供了一套简单可靠的解决方案,帮助开发

weixin_33997389的博客 302

电商秒杀场景下,如何用Redis+Lua脚本实现库存原子性扣减(附完整代码)

本文详细解析了在电商秒杀等高并发场景下,如何利用Redis配合Lua脚本实现库存扣减的原子性操作,有效防止超卖问题。通过核心架构设计、完整的Lua脚本代码示例以及缓存与数据库的最终一致性保障方案,为开发者提供了一套经过实战检验的高性能、高可用的库存管理解决方案。

sand8的博客 142

基于Redis+Lua实现分布式锁模拟秒杀扣减库存业务(非常详细,良心解析)

最近和几个小伙伴聊了聊基于Redis的分布式锁实现秒杀扣减库存业务的一些技术细节,刚好最近钻研了一段时间,本篇内容通过1个详细的案例,把这个实现方案作个记录,当做自己对知识的总结积累,同时也欢迎广大开发者朋友一起交流,学习,大家可以留言讨论,原创写作不易,请勿喷,如果觉得有用,不要忘了关注点赞哦。 前言 首先我们可以讨论以下4个问题: 1、什么是分布式锁 ? 要说起分布式锁,首先要提到与分布式锁相对应的是线程锁、进程锁。 线程锁:主要用来给方法、代码块加锁。当某个方法或代码使用锁,在同一时刻仅有一

奋斗的IT青年 7187

redis+lua脚本实现秒杀扣减优惠卷库存 & SpringBoot环境+SpringDataRedis客户端

我在优快云中 翻了一圈 没有发现写使用RedisTaplate客户端来解决库存超卖的,大多数是使用Redison和各种分布式锁,那么由我来写一篇连小白都能使用的Redis+Lua脚本解决超卖的教程,欢迎大家白嫖。

Dajiaonew的博客 655

LUA+Reids实现库存秒杀预扣减 记录流水 以及自己的思考

摘要:该文档描述了基于Lua脚本和Redis实现的库存预扣减方案,通过原子性操作确保秒杀场景的高效性。Lua脚本包含库存检查、扣减和流水记录功能,其中流水记录采用Redis哈希结构存储操作日志,包含操作前后库存值、时间戳等信息。流水记录主要用于实现幂等操作和后续对账,确保Redis与数据库的一致性。流水记录会在完成对账或商品下架24小时后删除。整个方案通过原子性扣减和异步持久化机制,有效解决了高并发场景下的库存管理问题。

多多的博客 1024

redis lua脚本实战秒杀扣减库存

原创不易,转载请注明出处 文章目录前言1.redisson介绍2. redis lua脚本编写与执行3.redis减库存lua脚本4.实战4.1 减库存逻辑4.2 压测 前言 我们都知道redis是高性能高并发系统必不可少的kv中间件,它以高性能,高并发著称,我们常常用它做缓存,将热点数据或者是万年不变的数据缓存到redis中,查询的时候直接查询redis,减轻db的压力,分布式系统中我们也会拿它来做分布式锁,分布式id,幂等来解决一些分布式问题,redis也支持lua脚本,而且能够保证lua脚本执行.

猿上生活 5571

关于秒杀系统中订单库存扣减的实践

如何在高并发下高效的处理库存数据, 要保证高性能和高可用,大部分方案并不满足,今天就来聊聊高并发下库存加减那些事儿。

周沐子 3775

Redis配合Lua实现高并发防止秒杀超卖,实战源码解决方案

◆ 1:解决思路将活动写入 redis 中,通过 redis 自减指令扣除库存。◆2:添加 redis 常量commons/constant/RedisKeyConstant.java...

独行侠梦的博客 2492

库存扣减中的原子性扣减

高兵法场景下的库存扣减涉及到的问题

m0_47160811的博客 733

redis结合lua实现秒杀

我们都知道秒杀是一个高并发,大量请求的场景,如果每次秒杀,我们都直接去操作数据库,校验库存,扣减库存,大量请求的话,数据库肯定扛不住,会出现各种问题。那怎么办?数据库虽然扛不住,但是redis能抗,所以我们可以使用定时任务,提前将秒杀商品的库存同步到redis中,每次秒杀请求,扣减redis中的库存,然后异步修改数据库的库存。

qq_49721447的博客 1362
上一篇: 基于redis数据结构ZSET实现邀请人排行榜
下一篇: 基于redission+aop自定义分布式锁注解
AllowM
博客等级 码龄7年 111粉丝 29原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值