Redis实现乐观锁+秒杀场景demo

在Redis中,乐观锁通常是通过使用 WATCH、MULTI 、EXEC和DISCARD命令实现的。这种乐观锁机制允许客户端在执行事务期间监视一个或多个键,并且只有在事务执行期间没有其他客户端修改被监视的键时,才会执行事务。

应用场景:
  1. 库存控制:在电商系统中,通过乐观锁控制商品库存的增减操作,避免超卖或超卖的情况发生。
  2. 秒杀系统:在秒杀活动中,通过乐观锁控制用户抢购商品的库存,确保活动期间库存不会超卖。
  3. 限流控制:通过乐观锁实现对某个资源的限流操作,可以控制请求的并发数量,保护系统免受突发高并发的影响。
使用案例:

下面是一个简单的伪代码,简单演示如何在 Redis 中实现乐观锁:

cpp 复制代码
while(true){
    // 监视键
    WATCH key   
    
    // 开启事务
    MULTI
    
    // 事务中执行操作
    GET key
    SET key value
    
    try{        
        // 提交事务
        EXEC 
    }catch{
        // 如果事务执行失败(被监视的键被其他客户端修改了),执行 DISCARD
        DISCARD
    }
    
}

使用jedis实现秒杀场景的demo,通过乐观锁控制用户抢购商品的库存,确保活动期间库存不会超卖

java 复制代码
public class SecKillDemo {

    public static void main(String[] args) {
        Jedis jedis = new Jedis("localhost", 6379);

        // 初始化商品库存
        String productKey = "product:001";
        jedis.set(productKey, "5");

        String user = "user1";

        while (true) {
            try {
                jedis.watch(productKey);
                int remainingStock = Integer.parseInt(jedis.get(productKey));

                if (remainingStock > 0) {
                    Transaction tx = jedis.multi();
                    tx.decr(productKey);
                    tx.exec();
                    System.out.println(user + " 秒杀成功,剩余库存: " + (remainingStock - 1));
                } else {
                    System.out.println(user + " 秒杀失败,商品已售罄");
                }

                break;
            } catch (JedisDataException e) {
                System.out.println(user + " 秒杀失败,重新尝试秒杀");
            } finally {
                jedis.unwatch();
            }
        }

        jedis.close();
    }
}

注意:

在调用 exec() 方法后,会返回一个包含每个命令返回结果的列表,如果列表为空,则表示事务执行失败。当事务执行失败时,可以考虑让程序休眠一段时间后进行重试,而不是无限制地频繁重试,以避免耗尽系统资源导致栈内存溢出或其他问题。通过控制重试次数和重试间隔时间 ,可以有效地处理事务执行失败的情况,并降低系统负担(无限重试会导致栈内存溢出)。

ps:以下是我整理的java面试资料,密码是obht,感兴趣的可以看看。最后,创作不易,觉得写得不错的可以点点关注!

链接:https://www.yuque.com/u39298356/uu4hxh?# 《Java面试宝典》

相关推荐
懂点Tech41 分钟前
ctfshow misc28:GIF 高度修改解题与脚本实现
开发语言·windows·python
云和数据.ChenGuang1 小时前
Python 重写(Override)深度解析:从 MRO 到 super() 的完整机制
java·开发语言·人工智能·python·langchain·1024程序员节
摇滚侠1 小时前
《On Java 中文版 基础卷》阅读笔记 实现隐藏 12
java·数据库·笔记
川石课堂软件测试2 小时前
学习软件测试需掌握的一些知识
数据库·python·sql·功能测试·网络协议·mysql·http
美狐美颜SDK开放平台2 小时前
视频美颜SDK试用DEMO阶段应该测试什么?直播APP接入实操指南
开发语言·人工智能·深度学习·音视频·美颜sdk·直播美颜sdk·第三方美颜sdk
dtq04242 小时前
C++小案例 - 日志实战
开发语言·c++
星夜离尘562 小时前
MATLAB ADC 码流触顶诊断:命中数、缺口分段与削顶不可辨识性
开发语言·matlab
2501_937767162 小时前
自建 SQL 数据库定时备份踩坑复盘与落地思路
数据库·sql
码匠许师傅3 小时前
【C++三方组件】Qt 概览:桌面 C++ 的事实标准与许可证三轨
开发语言·c++·qt
Cosolar3 小时前
不收费、不加水印、数据归你:我做了个开源的在线简历工具
后端·面试·前端框架