redis 7.乐观锁、悲观锁,Redis事务,秒杀案例,redisTemplate执行事务操作和LUA脚本

电商库存并发控制解决方案:从乐观锁到Redis原子操作实践 库存管理是电商系统的核心技术模块,其核心原理在于保证高并发场景下的数据一致性。通过数据库事务隔离级别、锁机制等并发控制技术,可以有效避免超卖和数据竞争问题。在技术价值层面,健壮的库存系统能够提升用户体验和系统稳定性,支撑秒杀等高并发业务场景。具体到应用场景,电商下单、促销活动等都需要可靠的库存扣减机制。本文针对库存不足异常,详细分析了乐观锁、Redis原子操作、数据库行级锁等多种解决方案,并提供了完整的代码示例和配置优化建议,帮助开发者构建高性能的库存管理系统。 阅读详情


一.超卖问题

1.1 出现原因

  在多个用户同时发起对同一个商品的下单请求时,先查询商品库存,再修改商品库存,会出现资源竞争问题,导致商品被超卖。

在这里插入图片描述

1.2 乐观锁、悲观锁

1.2.1 悲观锁

  对于数据冲突,持一种悲观的态度,先以一种预防的姿态在修改数据之前加锁,然后再对数据进行读写,在它释放锁之前其他任何人不能对其数据进行操作,直到锁被释放。一般关系型数据库的锁机制都是基于悲观锁的,如oracle中select ... for update

特点:完全保证数据的独占性和正确性,但是加锁释放锁的过程会造成消耗性能不高

1.2.2 乐观锁

  对于数据冲突,持一种乐观态度,操作数据时不会对操作的数据进行加锁(这使得多个任务可并行操作数据),等到数据提交时再验证数据是否存在冲突(CAS 即 check-and-set 一般通过版本号对比的方式实现);

特点:乐观锁是一种并发类型的锁,本身不对数据进行加锁通而是通过业务实现锁的功能,省掉了对数据加锁和解锁的过程,可一定程度上提高性能。但是在并发非常高的情况下,CAS导致大部分操作无功而返而浪费资源,因此在高并发的场景下,乐观锁的性能反而不如悲观锁。

1.3 redis乐观锁

  MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事务相关的命令;事务带有2个重要属性:
  事务是一个单独的隔离操作:事务中的所有命令都会序列化、按顺序地执行。事务在执行的过程中,不会被其他客户端发送来的命令请求所打断。
  事务是一个原子操作:事务中的命令要么全部被执行,要么全部都不执行。

1.3.1 MULTI

   MULTI 执行之后, 客户端可以继续向服务器发送任意多条命令, 这些命令不会立即被执行, 而是被放到一个队列中
在这里插入图片描述

1.3.2 EXEC

   exec命令负责触发并执行事务中的所有命令:
在这里插入图片描述

如果客户端在使用 MULTI 开启了一个事务之后,却因为断线而没有成功执行 EXEC ,那么事务中的所有命令都不会被执行;
如果客户端成功在开启事务之后执行 EXEC ,那么事务中的所有命令都会被执行。

1.3.3 事务中的错误

使用事务时可能会遇上以下两种错误:

   事务在执行 EXEC 之前,入队的命令可能会出错。比如,命令可能会产生语法错误(参数数量错误,参数名错误等),或者其他更严重的错误,比如内存不足(如果服务器使用 maxmemory 设置了最大内存限制的话)。从 Redis 2.6.5 开始,服务器会对命令入队失败的情况进行记录,并在客户端调用 EXEC 命令时,拒绝执行并自动放弃这个事务。
在这里插入图片描述

   命令可能在 EXEC 调用之后失败。如,事务中的命令可能处理了错误类型的键,比如将列表命令用在了字符串键上面。在 EXEC 命令执行之后所产生的错误, 并没有对它们进行特别处理: 即使事务中有某个/某些命令在执行时产生了错误, 事务中的其他命令仍然会继续执行。
在这里插入图片描述

1.3.4 DISCARD

   当执行 DISCARD 命令时, 事务会被放弃, 事务队列会被清空, 并且客户端会从事务状态中退出

在这里插入图片描述

1.3.5 WATCH

WATCH 命令为 Redis 事务提供 check-and-set (CAS)操作。

   被 WATCH 的键会被监视是否被改动过了。 如果有至少一个被监视的键在 EXEC 执行之前被修改了, 那么整个事务都会被取消。
客户端 1启动监听,并正在进行set操作:
在这里插入图片描述
客户端2同时修改键k11的值:
在这里插入图片描述
客户端1exec提交事务,执行失败
在这里插入图片描述

注:使用UNWATCH 命令可以手动取消对键的监视。

1.4 超卖问题解决

1.4.1 利用乐观锁淘汰用户,解决超卖问题:

在这里插入图片描述

@RestController
@RequestMapping("/redisTest")
public class RedisTestController {
    @Autowired
    private RedisTemplate redisTemplate;

    @PostMapping("/secKill")
    public boolean testRedis(String uid, String prodid) {
        /*模拟不同用户*/
        Random random = new Random();
        int i = random.nextInt(10000);
        uid = uid + i;
        //1 uid和prodid非空判断
        if (uid == null || prodid == null) {
            return false;
        }

        String kcKey = "sk:" + prodid + ":qt";
        String userKey = "sk:" + prodid + ":user";

        /*redisTemplate 开启事务支持*/
        redisTemplate.setEnableTransactionSupport(true);
        /*监视库存*/

        redisTemplate.watch(kcKey);
        String kc = redisTemplate.opsForValue().get(kcKey).toString();
        if (kc == null) {
            System.out.println("秒杀还没有开始,请等待");
            return false;
        }
        if (redisTemplate.opsForSet().isMember(userKey, uid)) {
            System.out.println("已经秒杀成功了,不能重复秒杀");
            return false;
        }
        if (Integer.parseInt(kc) <= 0) {
            System.out.println("秒杀已经结束了");
            return false;
        }
        redisTemplate.multi();
        redisTemplate.opsForValue().decrement(kcKey, 1);
        redisTemplate.opsForSet().add(userKey, uid);
        List exec = redisTemplate.exec();
        if (exec == null || exec.size() == 0) {
            System.out.println("秒杀失败,晚了一步,重新秒杀");
            return false;
        }
        return true;
    }
}

使用ab压测工具,执行命令:

ab -n 20000 -c 2000 -k -p ./postfile -T application/x-www-form-urlencoded http://192.168.0.109:8080/redisTest/secKill

在这里插入图片描述
结果发现:
在这里插入图片描述

注:

RedisTemplate 的默认配置不支持事务

(a) 在代码中若不添加 redisTemplate.setEnableTransactionSupport(true);则抛出
异常io.lettuce.core.RedisCommandExecutionException: ERR EXEC without MULTI

在这里插入图片描述
此时ab压测仍然发现超卖现象
在这里插入图片描述

(b) 更常见的写法仍是采用 RedisTemplate 的默认配置,通过使用 SessionCallback,该接口保证其内部所有操作都是在同一个Session中。

    SessionCallback<Object> callback = new SessionCallback<Object>() {
        @Override
        public Object execute(RedisOperations operations) throws DataAccessException {
            operations.multi();
             添加逻辑
            return operations.exec();
        }
    };
   redisTemplate.execute(callback));

二.库存遗留

2.1 库存遗留

  高并发情况下,CAS导致大部分请求失败。
在这里插入图片描述
2000个请求,500的库存,仍然有库存剩余
在这里插入图片描述

2.2 LUA脚本

  Lua 是一个小巧的脚本语言,Lua脚本可以被C/C++ 代码调用,也可以调用C/C++的函数,
LUA

2.2.1 redis中的LUA脚本

  将复杂的或者多步的redis操作,写为一个脚本,一次提交给redis执行,减少反复连接redis的次数。

  Redis 使用单个 Lua 解释器去运行所有脚本,保证脚本会以原子性(atomic)的方式执行: 当某个脚本正在运行的时候,不会有其他脚本或 Redis 命令被执行。 这和使用 MULTI / EXEC 包围的事务很类似。 在其他别的客户端看来,脚本的效果(effect)要么是不可见的(not visible),要么就是已完成的(already completed)。 另一方面,这也意味着,执行一个运行缓慢的脚本并不是一个好主意。当不得不使用一些跑得比较慢的脚本时,其他客户端会因为服务器正忙而无法执行命令。

2.2.2 通过lua脚本解决秒杀问题

  redis 2.6版本以后,通过lua脚本解决争抢问题,实际上是redis 利用其单线程的特性,用任务队列的方式解决多任务并发问题。

2.2.3 redisTemplate执行LUA脚本

@RestController
@RequestMapping("/redisTest")
public class RedisTestController {
    @Autowired
    private RedisTemplate redisTemplate;

    String secKillScript = "local userid=KEYS[1];\r\n" +
            "local prodid=KEYS[2];\r\n" +
            "local qtkey='sk:'..prodid..\":qt\";\r\n" +
            "local usersKey='sk:'..prodid..\":usr\";\r\n" +
            "local userExists=redis.call(\"sismember\",usersKey,userid);\r\n" +
            "if tonumber(userExists)==1 then \r\n" +
            "   return 2;\r\n" +
            "end\r\n" +
            "local num= redis.call(\"get\" ,qtkey);\r\n" +
            "if tonumber(num)<=0 then \r\n" +
            "   return 0;\r\n" +
            "else \r\n" +
            "   redis.call(\"decr\",qtkey);\r\n" +
            "   redis.call(\"sadd\",usersKey,userid);\r\n" +
            "end\r\n" +
            "return 1";


    @PostMapping("/secKill")
    public boolean testRedis(String uid, String prodid) {
        /*模拟不同用户*/
        Random random = new Random();
        int i = random.nextInt(10000);
        uid = uid + i;
        //1 uid和prodid非空判断
        if (uid == null || prodid == null) {
            return false;
        }
        //调用lua脚本并执行
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        redisScript.setResultType(Long.class);//返回类型是Long
        redisScript.setScriptText(secKillScript);
        Object execute = redisTemplate.execute(redisScript, Arrays.asList(uid, prodid), "mypar");


        String reString = String.valueOf(execute);
        if ("0".equals(reString)) {
            System.err.println("已抢空!!");
            return false;
        } else if ("1".equals(reString)) {
            System.out.println("抢购成功!!!!");
            return true;
        } else if ("2".equals(reString)) {
            System.err.println("该用户已抢过!!");
            return false;
        } else {
            System.err.println("抢购异常!!");
            return false;
        }

    }
}
使用RedisTemplate执行lua脚本时排错记录 redis中执行lua脚本相关知识 redistemplate调用lua脚本相关知识 自己错误记录 阅读详情

相关推荐

JAVA SpringBoot中使用redis的事务

1、自定义redisConfig , 如果项目中要使用redis事务,最好将用事务和不用事务的redis分开。

lyp131422的博客 1026

【Redis】RedisTemplate事物操作

Redis对事务的支持很简单,当一个客户端连接Redis服务时,发出MULTI命令就行进入事务,在执行MULTI命令之后,所要执行的命令并不会执行,而是进入到一个队列中,当最后执行EXEC命令后,才会执行对redis的操作命令,DISCATD为回滚事务。 RedisTemplate提供了MULTI、EXEC、DISCATD命令的封装,代码如下: redisTemplate.setEnableTransactionSupport(true); redisTemplate.m...

niuchenliang524的博客 6642

SpringBoot秒杀系统实战:高并发架构设计与核心解决方案

高并发系统设计是后端开发的核心挑战之一,其关键在于如何应对瞬时流量洪峰,保障系统的稳定与高性能。其基本原理通常涉及流量控制、资源隔离与异步处理,通过限流、缓存、消息队列等技术组合,实现系统压力的平滑过渡。在电商、社交、金融等互联网应用场景中,高并发处理能力直接决定了用户体验与业务成败。本文聚焦于经典的电商秒杀场景,深入探讨如何利用Redis实现原子性的库存扣减与防超卖,并结合消息队列完成异步削峰与最终一致性,为构建稳健的高并发服务提供一套可落地的工程实践方案。

weixin_30954265的博客 302

使用RedisTemplate执行lua脚本

springboot使用RedisTemplate执行lua脚本业务场景pom文件中引入redis 依赖redis 配置类实现的lua脚本实现的java代码实现功能过程中遇到的一些坑 业务场景 .不同的地区办理业务生成的文件编号格式必须要求为:当前年月+5位数字,且数字是从00001开始递增。最开始想的解决办法是生成自增序列去实现,但是由于地区数量太多,不能每个地区都整一个序列,所以这个方案就不行了。于是想到用redis去实现这个业务场景。由于对redis和lua 脚本的不熟悉,所以此次做一个开发过程的问题

技术进阶从入门到放弃 1万+

SpringBoot通过RedisTemplate执行Lua脚本的方法步骤

主要介绍了SpringBoot通过RedisTemplate执行Lua脚本的方法步骤,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

图形学基础|基于SDF的卡通阴影图

图形学基础|基于SDF的卡通阴影图 文章目录图形学基础|基于SDF的卡通阴影图一、前言二、SDF(Signed Distance Field)三、阴影图生成3.1 SDF生成3.2 插值参考博文 一、前言 回顾之前做的卡通渲染,角色面部阴影是靠一张阴影贴图实现的。 为了更好地控制角色的脸部阴影,通过计算脸部朝向与光照方向的夹角和一张单色的FaceMap来判断。 FaceMap的每个像素表示:该像素判断为阴影时候需要达到的夹角。 例如: 当方向光正对角色的时候,夹角为0°,对应的值为0,此时,FaceMap

【黑键】 1万+

Redis分布式锁原理之实现秒杀抢优惠卷业务

背景优惠券秒杀有两个业务涉及线程并发问题,第一个是库存超卖,第二个是一人一单,这就必须采取锁的方案了。下面根据优惠券秒杀功能一步一步进行展开,利用悲观锁、同步锁、分布式锁等方案循序渐进解决各种问题。

me_1984的博客 3628

RV1126上YOLOv8部署实战:从模型转换到板端推理的完整避坑指南

本文提供了在瑞芯微RV1126芯片上部署YOLOv8目标识别算法的完整实战指南。内容涵盖从模型转换、环境搭建到板端推理代码编写的全流程,重点解析了RKNN-Toolkit使用、量化配置、内存优化及后处理实现等关键环节的常见问题与解决方案,旨在帮助开发者高效避坑,实现边缘AI应用的稳定落地。

pz89012345的博客 567

黑马点评项目 | Redis学习笔记「纯享版」10w字超详细总结(含资料)

这次笔记是本人二刷Redis实战篇黑马点评的8w字汇总笔记。如果需要资料,于本文末尾查找即可

2025优快云博客之星Top246,后端开发技术领域新星创作者。 3万+

Java本地AI推理初体验:Jlama+LangChain4j构建离线问答系统

Jlama 是专为 Java 生态设计的现代化大型语言模型(LLM)推理引擎,旨在让开发者无需依赖外部服务即可直接在 Java 应用中运行本地化模型推理。本文将结合Jlama + langchain4j 实现一个本地可运行的简单问答Demo。

2501_92589102的博客 407

AWS RDS 介绍 三)创建 RDS 实例

AWS RDS 介绍 共分为 7 个部分, 其中 第 3部分重点介绍,如何创建一个RDS 实例。 三) AWS RDS 试用MySQL http://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/CHAP_GettingStarted.CreatingConnecting.MySQL.

XuYongshi02的专栏 7645

Redis分布式锁实现解析 - 结合秒杀业务

1.2. 获取事务的代理对象,防止事务的失效,同时暴露代理对象解决超卖问题:认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行。例如SynchronizedLock都属于悲观锁乐观锁:认为线程安全问题不一定会发生,因此不加锁,只是在更新数据时去判断有没有其它线程对数据做了修改。如果没有修改则认为是安全的,自己才更新数据。如果已经被其它线程修改说明发生了安全问题,此时可以重试或异常。分布式锁: 使用setnx 实现 多jvm 的锁监视器,(多进程可见)

weixin_65550740的博客 977

思维链:让AI更接近人类思维的技术

本文将探讨一种名为“思维链”的技术,它旨在让AI更接近人类思维。文章首先介绍了问题背景与核心概念,接着讲解了算法原理和数学模型,随后阐述了系统分析与架构设计,最后通过项目实战展示了思维链的实际应用,并提供了最佳实践和小结。思维链是一种旨在模拟人类思维过程的技术,它通过构建一系列相互关联的思维方式,实现对复杂问题的分析和解决。思维链算法是一种基于人类思维过程的人工智能算法,它通过构建一系列思维链,实现对问题的分析和解决。智能问答系统是一种常见的人工智能应用,它能够回答用户提出的各种问题。

AI天才研究院 942

【大白话说Java面试题 第116题】【并发篇】第16题:什么样的场景适合用悲观锁,什么样的场景适合用乐观锁?

本文探讨了悲观锁与乐观锁的适用场景,提出三维评估法(冲突概率、一致性要求、操作复杂度)作为选型决策模型。悲观锁适用于金融交易、库存扣减、订单状态流转等强一致性且高冲突场景,而乐观锁更适合读多写少(如商品浏览)、低频更新(如用户信息)或最终一致性要求(如统计累加)的场景。决策关键在于量化业务特征,平衡性能与一致性需求,避免一刀切的选择。

Java后端 | AI智能体应用实战派 | 电脑技能行家 262

Coze智能体实战:接口需求分析和接口调试

AI智能体的需求:能根据接口文档提取接口信息以及设计接口测试点,并进行接口调试返回接口测试结果。

十二测试录 282

Opencv项目实战:20 单手识别数字0到5

今天要做的是单手识别数字0到5,通过在窗口展示,实时的展示相应的图片以及文字。在这里,我提供一下识别更多数字的方法(0-10)。首先最简便的是双手识别,完全不用更改代码,把图片处理好就行了;其次,就是按照最上面的那张图片,参数figureup是一个长度为5的列表[0,0,0,0,0],你可以参照着手势将其打印出来,然后将其用if条件判断。当然,在我们这边最常见的还是华北手势表示数字,大家按照自己的习惯来就行。

m0_62919535的博客 2875

高并发场景下资源公平分配系统设计:从乐观锁到Redis的实战方案

在分布式系统与高并发编程领域,资源竞争与分配是核心挑战之一,其本质在于解决多线程或多进程环境下对有限共享资源的访问冲突。其基本原理是通过锁机制、原子操作或队列等技术,协调并发请求的执行顺序,确保数据的一致性与业务的正确性。这项技术的核心价值在于保障系统的强一致性、公平性与高可用性,避免超卖、数据错乱等经典问题。典型的应用场景包括电商秒杀、票务抢购、活动报名、任务调度等瞬时高流量业务。本文以社区活动报名这一具体场景为例,深入探讨了在存在复杂业务规则(如“邻居”约束)下,如何设计健壮的竞斗分配机制。文中详细对比

weixin_34184158的博客 405

Open3D——直通滤波(python详细过程版)【2025最新版】

python就一个字:强。博客长期更新,本文最近更新时间为:2025年1月11日。

点云侠的博客 7514

Redis事务深入:MULTI/EXEC、WATCH乐观锁与Lua脚本实战对比

数据库事务是保证一致性的基础概念,Redis则以MULTI/EXEC命令队列实现原子执行。其乐观锁机制通过WATCH监视key,在并发读改写场景防止冲突,但无回滚设计让不少开发者误解。为应对高并发扣库存等应用场景,Lua脚本将判断与写入原子化,成为比WATCH加重试更高效的选择。本文从命令执行链路、错误分类到集群限制,并结合秒杀、库存扣减等实践,帮助工程师正确选型Redis事务相关技术。

weixin_32306957的博客 287

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

Redis

内存和磁盘:内存(RAM)能够暂时获取硬盘上的数据,此时cpu和内存打交道,运行速度较快,关机退出会清空,磁盘(disk),其实就是硬盘。session数据会保存在服务端,但是返回前端的时候会返回一个“钥匙”,这把“钥匙”就是 JSESSIONID ,没找到(钥匙过期了或假的):直接给你开一个新的柜子,发一把新钥匙,把新柜子给你。所以没完成登录,就会新开一个柜子,而新柜子就拿不到任何的数据,拦截器无法通过。如果没有钥匙:直接给你开一个新的柜子,发一把新钥匙,把新柜子给你。NoSql不同的数据结构的。

lkGdZHANG的博客 62

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

秒杀系统如何设计

秒杀系统设计需解决三大核心问题:高并发、超卖和恶意请求。系统架构采用分层限流+异步削峰策略,通过CDN、前端验证、网关限流等多层拦截,将流量层层过滤。核心方案是Redis原子扣减库存+MQ异步下单,使用Lua脚本确保库存操作的原子性,避免超卖。最终只有少量请求进入数据库,实现高并发下的稳定可靠。

xiaokjv的博客 217

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Redis事务机制深度解析:不回滚真相、核心命令与Lua实战

Redis作为高并发场景下的核心组件,其事务机制常被开发者与MySQL事务混淆。MULTI/EXEC命令队列的设计让一组命令在单线程模型下串行执行,确保执行期间不被其他客户端插入,但运行时错误却不会触发回滚,导致部分成功部分失败的结果。理解事务的入队阶段与执行阶段的差异,是掌握Redis事务原理的关键。在秒杀抢购、库存扣减、订单流水等高频写操作中,开发者需要明确事务与Lua脚本的能力边界,借助服务端脚本实现整体原子性。从核心命令解析到生产环境实践,全面梳理Redis事务的适用场景与替代方案,帮助读者在面试与

weixin_29913663的博客 244

基于Redis与Spring Boot构建高并发资源排队系统的技术实践与风险防范

在分布式系统架构中,请求调度与资源分配是核心基础概念,其技术原理通常涉及队列管理、并发控制和数据一致性。通过实现公平、可靠的排队机制,能够有效解决高并发场景下的资源争抢问题,保障系统的稳定性和用户体验。这一技术具有重要的工程实践价值,广泛应用于电商秒杀、票务预约、云资源申购以及游戏内限量物品发放等场景。本文以游戏开发或虚拟经济中的稀缺资源分配为具体切入点,深入探讨了使用Redis有序集合与Spring Boot构建健壮排队系统的实现方案,并重点分析了在高并发环境下如何通过乐观锁、原子操作等手段防止库存超卖,

weixin_33768481的博客 322

04-04-A-Redis客户端选型与实战

本文系统对比Jedis、Lettuce、Redisson三大客户端,明确RedisTemplate(数据存取)与Redisson(分布式协调)的互补关系。通过决策树与分场景对照表,指导企业级选型:缓存读写用RedisTemplate,分布式锁、限流、延迟队列等用Redisson。强调两者共存落地,避免盲目替代,结合Maven配置、Spring Boot集成及核心机制(如看门狗、Lua加锁),提供可直接落地的实战方案。

hhkrye的博客 311

基于SpringBoot与Vue的数码产品抢购系统设计与实现(含高并发秒杀)

高并发秒杀是互联网业务中的典型挑战,瞬时流量下如何保证库存扣减的原子性、接口的幂等性以及系统的削峰能力,直接决定了项目的技术含金量。SpringBoot作为主流后端框架,结合Vue构建前后端分离应用,已成为企业级开发的标准范式。在秒杀场景中,通过数据库乐观锁、Redis+Lua原子脚本、消息队列异步下单等方案,可以有效解决超卖和重复下单问题。这类技术不仅适用于电商抢购,还能迁移至票务预约、限量发售等业务。本文以数码产品抢购系统为例,从系统设计、数据库建模、后端并发控制到前端交互,完整剖析高并发项目的落地思路

weixin_34246551的博客 412

基于Redis SETNX的秒杀系统演进:从单机锁到集群分布式锁

高并发场景下,秒杀系统的核心不再是简单的读请求,而是分布式并发写的一致性难题。Redis 凭借单线程模型和内存级性能,天然适合承担库存扣减这类高频写操作,但仅依赖单线程特性无法避免竞态条件,必须借助 SETNX 这样具备原子性的命令。从用户资格占位、防重复下单,到结合 Lua 脚本实现“检查库存+扣减”的原子操作,再到集群环境下分布式锁的可靠性演进,每一步都直接影响到系统的正确性与吞吐量。文章从 Redis 原子性原理出发,剖析 SETNX 在秒杀场景中的核心价值,并串联限流、异步削峰、熔断降级等工程实践,

weixin_34146805的博客 352
上一篇: ab压测- Apache HTTP server benchmarking tool
下一篇: redis 8.Redis持久化之RDB (如何触发RDB快照;rdb备份恢复)
但行益事莫问前程
但行益事莫问前程 新星创作者: 数据库技术领域 新星创作者: 数据库技术领域
博客等级 码龄7年 8490粉丝 225原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

但行益事莫问前程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值