当前位置: 首页 > news >正文

【分布式锁】Redission实现分布式锁

接着上一节,我们遇到了超卖的问题,并通过Redis实现分布式锁,进行了解决。本节 我将换一种方式实现分布式锁。

前提:
nginx、redis、nacos
模块1:
provider-and-consumer 端口 8023
模块2
rabbitmq-consumer 端口 8021

添加依赖

<dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.15.6</version>
</dependency>

业务代码

模块1代码 RedisTestController.java

package com.atguigu.gulimall.providerconsumer.controller;import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.UUID;
import java.util.concurrent.TimeUnit;/*** @author: jd* @create: 2024-07-08*/
@RestController
@RequestMapping("/test")
@Slf4j
public class RedisTestController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Autowiredprivate RedissonClient redissonClient;@GetMapping("/RedissonLock")public String  deductStockByRedisson(){//写死一个固定商品ID,作为我们被秒杀的商品String lockKey="lock:product:102";//获取锁对象RLock lock = redissonClient.getLock(lockKey);//加锁,使用lock方法,锁将会自动续命lock.lock();try{//获取当前库存String stock1 = stringRedisTemplate.opsForValue().get("stock");if(stock1==null){System.out.println("秒杀未开始,请等开始后操作下单");return "end";}int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));if(stock>0){// 扣减库存int realStock = stock - 1;// 更新库存stringRedisTemplate.opsForValue().set("stock", realStock + "");System.out.println("扣减成功,剩余的库存为:" + realStock);}else {System.out.println("扣减库存失败,库存不足");}}finally {if(lock.isLocked()&&lock.isHeldByCurrentThread()){//释放分布式锁lock.unlock();System.out.println("分布式锁释放"); //解锁}}return "end";}}

模块2代码 RedisTestController.java

package com.atguigu.gulimall.rabbitmqconsumer.controller;import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.UUID;
import java.util.concurrent.TimeUnit;/**** 和provider-and-consumer 这两个服务中都有这个RedisTestController,用来模拟两个不同的服务* @author: jd* @create: 2024-07-08*/
@RestController
@RequestMapping("/test")
@Slf4j
public class RedisTestController {@Autowiredprivate StringRedisTemplate stringRedisTemplate;@Autowiredprivate RedissonClient redissonClient;@GetMapping("/RedissonLock")public String  deductStockByRedisson(){//写死一个固定商品ID,作为我们被秒杀的商品String lockKey="lock:product:102";//获取锁对象RLock lock = redissonClient.getLock(lockKey);//加锁,使用lock方法,锁将会自动续命lock.lock();try{//获取当前库存String stock1 = stringRedisTemplate.opsForValue().get("stock");if(stock1==null){System.out.println("秒杀未开始,请等开始后操作下单");return "end";}int stock = Integer.parseInt(stringRedisTemplate.opsForValue().get("stock"));if(stock>0){// 扣减库存int realStock = stock - 1;// 更新库存stringRedisTemplate.opsForValue().set("stock", realStock + "");System.out.println("扣减成功,剩余的库存为:" + realStock);}else {System.out.println("扣减库存失败,库存不足");}}finally {if(lock.isLocked()&&lock.isHeldByCurrentThread()){//释放分布式锁lock.unlock();System.out.println("分布式锁释放"); //解锁}}return "end";}}

测试结果:
单次请求,我发送两次,结果:
在这里插入图片描述

在这里插入图片描述

第二次:

在这里插入图片描述

成功扣减。

并发情况模拟:
当前库存数
在这里插入图片描述
压测:
在这里插入图片描述
并发压测结果:
8023模块

扣减成功,剩余的库存为:83
分布式锁释放
扣减成功,剩余的库存为:81
分布式锁释放
扣减成功,剩余的库存为:80
分布式锁释放
扣减成功,剩余的库存为:78
分布式锁释放
扣减成功,剩余的库存为:76
分布式锁释放
扣减成功,剩余的库存为:75
分布式锁释放
扣减成功,剩余的库存为:72
分布式锁释放
扣减成功,剩余的库存为:68
分布式锁释放
扣减成功,剩余的库存为:66
分布式锁释放
扣减成功,剩余的库存为:64
分布式锁释放
扣减成功,剩余的库存为:62
分布式锁释放
扣减成功,剩余的库存为:60
分布式锁释放
扣减成功,剩余的库存为:58
分布式锁释放
扣减成功,剩余的库存为:56
分布式锁释放
扣减成功,剩余的库存为:54
分布式锁释放
扣减成功,剩余的库存为:52
分布式锁释放
扣减成功,剩余的库存为:50
分布式锁释放
扣减成功,剩余的库存为:48
分布式锁释放
扣减成功,剩余的库存为:46
分布式锁释放
扣减成功,剩余的库存为:44
分布式锁释放
扣减成功,剩余的库存为:42
分布式锁释放
扣减成功,剩余的库存为:40
分布式锁释放
扣减成功,剩余的库存为:38
分布式锁释放
扣减成功,剩余的库存为:36
分布式锁释放
扣减成功,剩余的库存为:34
分布式锁释放
扣减成功,剩余的库存为:32
分布式锁释放
扣减成功,剩余的库存为:30
分布式锁释放
扣减成功,剩余的库存为:28
分布式锁释放
扣减成功,剩余的库存为:26
分布式锁释放
扣减成功,剩余的库存为:24
分布式锁释放
扣减成功,剩余的库存为:22
分布式锁释放
扣减成功,剩余的库存为:20
分布式锁释放
扣减成功,剩余的库存为:18
分布式锁释放
扣减成功,剩余的库存为:16
分布式锁释放
扣减成功,剩余的库存为:14
分布式锁释放
扣减成功,剩余的库存为:12
分布式锁释放
扣减成功,剩余的库存为:10
分布式锁释放
扣减成功,剩余的库存为:8
分布式锁释放
扣减成功,剩余的库存为:6
分布式锁释放
扣减成功,剩余的库存为:4
分布式锁释放
扣减成功,剩余的库存为:2
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放

8021模块日志

扣减成功,剩余的库存为:82
分布式锁释放
扣减成功,剩余的库存为:79
分布式锁释放
扣减成功,剩余的库存为:77
分布式锁释放
扣减成功,剩余的库存为:74
分布式锁释放
扣减成功,剩余的库存为:73
分布式锁释放
扣减成功,剩余的库存为:71
分布式锁释放
扣减成功,剩余的库存为:70
分布式锁释放
扣减成功,剩余的库存为:69
分布式锁释放
扣减成功,剩余的库存为:67
分布式锁释放
扣减成功,剩余的库存为:65
分布式锁释放
扣减成功,剩余的库存为:63
分布式锁释放
扣减成功,剩余的库存为:61
分布式锁释放
扣减成功,剩余的库存为:59
分布式锁释放
扣减成功,剩余的库存为:57
分布式锁释放
扣减成功,剩余的库存为:55
分布式锁释放
扣减成功,剩余的库存为:53
分布式锁释放
扣减成功,剩余的库存为:51
分布式锁释放
扣减成功,剩余的库存为:49
分布式锁释放
扣减成功,剩余的库存为:47
分布式锁释放
扣减成功,剩余的库存为:45
分布式锁释放
扣减成功,剩余的库存为:43
分布式锁释放
扣减成功,剩余的库存为:41
分布式锁释放
扣减成功,剩余的库存为:39
分布式锁释放
扣减成功,剩余的库存为:37
分布式锁释放
扣减成功,剩余的库存为:35
分布式锁释放
扣减成功,剩余的库存为:33
分布式锁释放
扣减成功,剩余的库存为:31
分布式锁释放
扣减成功,剩余的库存为:29
分布式锁释放
扣减成功,剩余的库存为:27
分布式锁释放
扣减成功,剩余的库存为:25
分布式锁释放
扣减成功,剩余的库存为:23
分布式锁释放
扣减成功,剩余的库存为:21
分布式锁释放
扣减成功,剩余的库存为:19
分布式锁释放
扣减成功,剩余的库存为:17
分布式锁释放
扣减成功,剩余的库存为:15
分布式锁释放
扣减成功,剩余的库存为:13
分布式锁释放
扣减成功,剩余的库存为:11
分布式锁释放
扣减成功,剩余的库存为:9
分布式锁释放
扣减成功,剩余的库存为:7
分布式锁释放
扣减成功,剩余的库存为:5
分布式锁释放
扣减成功,剩余的库存为:3
分布式锁释放
扣减成功,剩余的库存为:1
分布式锁释放
扣减成功,剩余的库存为:0
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放
扣减库存失败,库存不足
分布式锁释放

可以看到,没有超卖现象。至此Redission实现分布式锁已经OK。
redis实现分布式锁 可见博文:【分布式锁】Redis实现分布式锁

http://www.lryc.cn/news/405774.html

相关文章:

  • UE4/5 对话系统
  • Golang | Leetcode Golang题解之第275题H指数II
  • Python—面向过程编程,详细讲解(类和实例,初始化函数,类中封装数据与操作)
  • Linux云计算 |【第一阶段】SERVICES-DAY2
  • el-upload照片墙自定义上传多张图片(手动一次性上传多张图片)包含图片回显,删除
  • 三星Unpacked发布会即将举行:有新款折叠屏手机,还有智能戒指
  • 【Python】Matplotlib简要教程
  • 数驭未来,景联文科技构建高质大模型数据库
  • 视频汇聚平台EasyCVR启动出现报错“cannot open shared object file”的原因排查与解决
  • VMware 安装完,设备管理器中没有虚拟网卡(vmnet0、wmnet1、vmnet8) / 虚拟网络编辑器中没有桥接模式
  • 构建高效Node.js中间层:探索请求合并转发的艺术
  • 中断和EXIT原理介绍
  • vcpkg或者命令行需要设置代理时如何设置
  • tensorflow安装及数据操作----学习笔记(一)
  • 顺序表和单链表的经典算法题
  • python基础知识点(蓝桥杯python科目个人复习计划71)
  • 【大数据专题】Flink题库
  • Python鲁汶意外莱顿复杂图拓扑分解算法
  • 【C++】类和对象之继承
  • 如何在LlamaIndex中使用RAG?
  • css气泡背景特效
  • 7.23模拟赛总结 [数据结构优化dp] + [神奇建图]
  • MySQL-视 图
  • PHP SimpleXML
  • 【Spring Boot 自定义配置项详解】
  • 电机相位接线错误导致的潜在问题
  • react中如何mock数据
  • 通过Faiss和DINOv2进行场景识别
  • 新手入门基础Java
  • 2024最新版虚拟便携空调小程序源码 支持流量主切换空调型号