【分布式锁】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.mzph.cn/news/874880.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

成都云飞浩容文化传媒有限公司电商服务新领航者

在电商的海洋里&#xff0c;无数企业如同繁星般闪烁&#xff0c;但其中有一颗璀璨的明星——成都云飞浩容文化传媒有限公司&#xff0c;以其专业的电商服务和独特的创新理念&#xff0c;成为行业的佼佼者。今天&#xff0c;就让我们一起走进云飞浩容&#xff0c;探索这家公司的…

# Redis 入门到精通(八)-- 服务器配置-redis.conf配置与高级数据类型

Redis 入门到精通&#xff08;八&#xff09;-- 服务器配置-redis.conf配置与高级数据类型 一、redis 服务器配置–redis.conf 配置 1、服务器端设定 1&#xff09;设置服务器以守护进程的方式运行&#xff1a; daemonize yes|no 2&#xff09;绑定主机地址&#xff1a; bin…

【防火墙】防火墙NAT、智能选路综合实验

实验拓扑 实验要求 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9&#xff0c;多出口环境基于带宽比例进行选路…

自动驾驶AVM环视算法–更新超广角视图算法和exe测试demo

1、测试环境 opencv310vs2022 2、使用的编程语言 c和c 3、测试的demo的获取 更新&#xff1a;测试的exe程序&#xff0c;无需解压码就可以体验算法测试效果 百度网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1ndDcJ6VwexZoLUyUXlwLwg 提取码&#xff1a;q1…

python-爬虫实例(1):获取京东商品评论

目录 前言 道路千万条&#xff0c;安全第一条 爬虫不谨慎&#xff0c;亲人两行泪 获取京东商品评论信息 一、实例示范 二、爬虫四步走 1.UA伪装 2.获取Url 3.发送请求 4.获取响应数据进行解析并保存 总结 前言 道路千万条&#xff0c;安全第一条 爬虫不谨慎&#xff0c;…

手机怎么恢复回收站清空的照片?2个技巧大公开(适用各类安卓机)

站在时间的边缘&#xff0c;凝视着那些即将消逝的回忆&#xff0c;心里的惆怅不断增加。我们到底该怎么恢复回收站删除的照片呢&#xff1f;请相信&#xff0c;这些回忆并未真正消失。 无论你是因为误操作还是其他原因导致回收站被清空&#xff0c;这篇文章都将为你提供有力的…

Centos7_Minimal安装Cannot find a valid baseurl for repo: base/7/x86_6

问题 运行yum报此问题 就是没网 解决方法 修改网络信息配置文件&#xff0c;打开配置文件&#xff0c;输入命令&#xff1a; vi /etc/sysconfig/network-scripts/ifcfg-网卡名字把ONBOOTno&#xff0c;改为ONBOOTyes 重启网卡 /etc/init.d/network restart 网路通了

慎用Float和Double进行浮点运算

背景 在之前的开发过程中, 遇到了一些小问题. 就是在某功能计算时, 按照当时的设想是需要保留两位小数并向下取整. 当时没有太好的思路, 于是请教了好朋友gpt同志. 而gpt给出3种思路: 使用String.format方法 double value 123.456789; String formattedString String.forma…

Redis从入门到超神-(五)Redis实现分布式锁原理

引言 什么是分布式锁&#xff1f; 分布式锁是分布式系统中用于控制多个进程或线程对共享资源的访问的一种机制。在分布式系统中&#xff0c;由于存在多个服务实例或节点&#xff0c;它们可能会同时尝试访问或修改同一份数据或资源。如果没有适当的同步机制&#xff0c;就可能导…

labview实现两台电脑共享变量传输及同步

因为工作需要&#xff0c;需要实现多台主机间进行数据传输&#xff0c; 有两个备选方案&#xff0c; 1&#xff1a;建立tcp&#xff0c;然后自己解包 2&#xff1a;就是通过共享变量传输 虽然共享变量也是建立在TCP/IP上面的&#xff0c;但是不用自己解包呀 关于共享变量网络上…

mysql面试(四)

前言 本章节有些长&#xff0c;主要的篇幅是介绍缓存页的算法&#xff0c;如何快速的定位哪些是没有用过的&#xff0c;哪些是用过的&#xff0c;哪些是要淘汰掉的。 建议可以阅读一下这里面LRU算法相关的内容&#xff0c;和很多组件里面基本原理都是想通的&#xff0c;比如re…

聊聊 C# 中的顶级语句

前言 在 C# 9.0 版本之前&#xff0c;即使只编写一行输出 “Hello world” 的 C# 代码&#xff0c;也需要创建一个 C# 类&#xff0c;并且需要为这个 C# 类添加 Main 方法&#xff0c;才能在 Main 方法中编写代码。从 C# 9.0 开始&#xff0c;C# 增加了 “顶级语句” 语法&…

redis原理之底层数据结构-跳表

1.什么是跳表 1.1 链表及其不足 链表是在程序设计中最常见的数据结构之一&#xff0c;它通过指针将多个链表节点连接起来&#xff0c;这样就可以将逻辑上同一类的数据存储到不连续的内存空间上。链表结构如下&#xff1a; 但是链表有一个问题&#xff0c;就是当链表需要查询一…

3.1 FreeRTOS详细移植步骤(自己的实操)

[TOC](3.1 FreeRTOS详细移植步骤(自己的实操)) 自己使用阿波罗F767的内存管理实验和定时器实验&#xff0c;进行复刻。 FreeRTOS源码版本是FreeRTOS 202212.01。官网和Github都有下载。 按照STM32F767FreeRTOS开发手册V1.1进行移植复刻。 注:这个开发手册不是开发指南。跟视频里…

关于Qt部署CMake导致“Failed to set working directory to”的问题

2024年7月23日补充&#xff1a;该目录过深的情况只在Win10上有发现&#xff0c;Win11则没有问题&#xff0c;且Win11可以在DevHome中设置LongPath。 --------------------------------------------------------------------------------------------------------------- 使用qt…

Spark_Oracle_II_Spark高效处理Oracle时间数据:通过JDBC桥接大数据与数据库的分析之旅

接前文背景&#xff0c; 当需要从关系型数据库&#xff08;如Oracle&#xff09;中读取数据时&#xff0c;Spark提供了JDBC连接功能&#xff0c;允许我们轻松地将数据从Oracle等数据库导入到Spark DataFrame中。然而&#xff0c;在处理时间字段时&#xff0c;可能会遇到一些挑战…

分布式Apollo配置中心搭建实战

文章目录 环境要求第一步、软件下载第二步、创建数据库参考文档 最近新项目启动&#xff0c;采用Apollo作为分布式的配置中心&#xff0c;在本地搭建huanj 实现原理图如下所示。 环境要求 Java版本要求&#xff1a;JDK1.8 MySql版本要求&#xff1a;5.6.5 Apollo版本要求&…

第八讲:Sysmac Studio控制器设置

控制器设置 一、控制器设定-操作设置 1、启动模式(运行模式/编程模式) 控制器上电后,希望程序运行还是不运行。如果说希望程序运行,那么就选择运行模式。如果说希望上电后程序不运行就选择编程模式。 通常情况下选运行模式可能会比较多一些。 2、SD内存卡设置 当控制…

Pytorch TensorBoard的使用

from torch.utils.tensorboard import SummaryWriter writer SummaryWriter("logs")for i in range(100):writer.add_scalar("yx",i,i) writer.close() 第一个参数 y2x: 这是图表的标题或标签。它会显示在TensorBoard界面中,帮助你识别这条曲线。 第二个参…

(35)远程识别(又称无人机识别)(二)

文章目录 前言 4 ArduRemoteID 5 终端用户数据的设置和使用 6 测试 7 为OEMs添加远程ID到ArduPilot系统的视频教程 前言 在一些国家&#xff0c;远程 ID 正在成为一项法律要求。以下是与 ArduPilot 兼容的设备列表。这里(here)有一个关于远程 ID 的很好解释和常见问题列表…