Redis乐观锁解决超卖问题

本文通过实例展示了如何利用Redis乐观锁解决秒杀场景下的超卖问题,详细介绍了使用Java代码实现秒杀操作,并通过ab工具进行并发测试确保方案的有效性。同时提供了在CentOS7和Windows上下载及使用ab工具的方法。
摘要由CSDN通过智能技术生成

Redis乐观锁解决超卖问题

情景假设:现在华为最新手机在做活动,双十二 00:00 准时前十名抢购的用户可以1元秒杀。而数据库对这个秒杀的动作呢,需要作出两个动作:
1、库存减1
2、记录秒杀成功的用户id
在这里插入图片描述
话不多说,我们直接用代码来演示:

这里直接给出控制器方法。

    @PostMapping("/secKill")
    public void TestSecKill(){
        /**
         *  实际开发,我们需要获取用户的id和商品的id
         *  这里作为学习使用,我们先写死
         */
        //用户id,我们使用随机数来表示每次访问的不同用户
        String userid = new Random().nextInt(50000) + "";
        //商品id,我们先写死
        String prodid = "1001";

        //1、连接redis(如果有设置requirepass的话,记得添加jedis.auth("你的密码");
        Jedis jedis = new Jedis("119.91.153.74", 6379);

        //2、拼接key
        String kcKey = "sk:"+prodid+":qt";  //库存key
        String userKey = "sk:"+userid+":user";  //秒杀成功用户key

        //使用乐观锁,监视库存
        jedis.watch(kcKey);

        //3、获取库存,为null表示活动未开始
        String kc = jedis.get(kcKey);
        if(kc == null){
            System.out.println("秒杀还未开始");
            jedis.close();
            return;
        }

        //4、判断用户是否重复秒杀
        if(jedis.sismember(userKey, userid)){
            System.out.println("您已成功秒杀,不可重复秒杀");
            jedis.close();
            return;
        }

        //5、库存小于等于0,秒杀结束
        if (Integer.parseInt(kc) <= 0){
            System.out.println("秒杀活动已结束,感谢您的参与");
            jedis.close();
            return;
        }

        //6、秒杀过程
        //开启事务
        Transaction transaction = jedis.multi();
        //组队
        //6.1 库存减1
        transaction.decr(kcKey);
        //6.2 添加秒杀成功用户
        transaction.sadd(userKey, userid);
        //执行
        List<Object> results = transaction.exec();
        //执行失败
        if (results == null || results.size() == 0){
            System.out.println("秒杀失败.....");
            jedis.close();
            return;
        }
        //执行成功
        System.out.println("恭喜您秒杀成功.......");
        jedis.close();
    }

然后我们来测试一下:
首先,先给redis添加库存:

set sk:1001:qt 10

然后我们使用ab工具模拟并发:
这里顺便介绍几个命令:

命令描述
-nrequests:请求次数
-cconcurrency:并发数
-Tcontent-type:用于POST和PUT请求,其值固定为’application/x-www-form-urlencoded’
-ppostfile:如果post请求有参数,要放到该文件中
-uputfile:如果put请求有参数,要放到该文件中

基本介绍就这么多,接下来我们直接用,使用命令:
注意:即使post请求没有参数,也要使用-p标签,否则好像会默认使用get请求,192.168.148.148是Tomcat服务器的ip地址(这里我的是我的windows的ip地址)。

ab -n 1000 -c 100 -p postfile -T ‘application/x-www-form-urlencoded’ http://192.168.148.148:8080/secKill

如果要查询自己本机的ip地址的话,在cmd下输入 ipconfig即可。它里面有一个Ipv4地址就是你的ip地址啦。

如果Linux服务器访问不了你的windows,那么我们也可以在windows上下载ab工具,并使用python来模拟我们的并发测试。

import os
#D:\Download\httpd-2.4.51-o111l-x64-vc15\Apache24\bin\ab是我们的ab工具路径
ab=os.popen(r'D:\Download\httpd-2.4.51-o111l-x64-vc15\Apache24\bin\ab -n 1000 -c 100 -p ./postfile -T application/x-www-form-urlencoded http://192.168.148.148:8080/secKill')
print(ab.read())

运行结果:(可以看到秒杀成功的次数是10次,成功解决了我们的超卖问题)
在这里插入图片描述
我们再去Redis下查看:
在这里插入图片描述
在这里插入图片描述

CentOS7下载ab工具

安装命令:

yum install httpd-tools

Windows下载ab工具

ab工具官网下载地址:https://www.apachehaus.com/cgi-bin/download.plx
进入后往下拉:
在这里插入图片描述
下载完成后直接解压即可。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
乐观锁和悲观锁是在并发控制中常用的两种方式,用于解决数据一致性问题。下面我将为您介绍一个关于Redis乐观锁和悲观锁的例子。 乐观锁的例子: 假设有一个电商平台,多个用户同时想要购买某个商品,但是该商品的库存只剩下1个。这时候使用乐观锁可以避免超卖问题。 1. 用户A和用户B同时请求购买该商品。 2. 服务器接收到购买请求后,首先查询该商品的库存数量,发现还有1个。 3. 服务器分别给用户A和用户B生成一个唯一的订单号,并将库存数量减1。 4. 用户A提交购买请求,服务器检查库存数量,发现仍然是1个。 5. 用户B提交购买请求,服务器检查库存数量,发现已经是0个。 6. 服务器将用户B的购买请求拒绝,并给用户B返回库存不足的提示。 7. 用户A的购买请求继续处理,生成订单并返回成功的提示。 在这个例子中,通过乐观锁的方式,多个用户同时发起购买请求时,并发控制的操作会保证只有一个用户能够成功购买商品。 悲观锁的例子: 假设有一个论坛系统,用户发帖时需要检查该用户是否被禁言,使用悲观锁可以避免用户在禁言期间仍然能够发帖的问题。 1. 用户A发起发帖请求。 2. 服务器接收到请求后,首先对该用户进行悲观锁的加锁操作,防止其他操作同时修改用户状态。 3. 服务器检查用户状态,发现用户A已经被禁言。 4. 服务器拒绝用户A的发帖请求,并返回禁言提示。 5. 服务器释放用户A的悲观锁,其他操作可以继续对用户进行修改。 在这个例子中,通过悲观锁的方式,可以确保在对用户状态进行操作时,其他操作无法同时修改用户状态,避免了用户在禁言期间仍然能够发帖的问题。 综上所述,乐观锁和悲观锁是在并发控制中常用的两种方式,用于解决数据一致性问题。通过对乐观锁和悲观锁的例子的说明,我们可以更好地理解和应用这两种锁机制。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值