redis的分布式事务-redisson

一  redisson

1.1 redisson分布式事务

Redisson分布式锁是一种基于redis实现的分布式锁,它利用redis的setnx命令实现分布式锁的互斥访问。同时还支持锁的自动续期功能,可以避免因为某个进程崩溃或者网络故障导致锁无法释放的情况。

只要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。

因此,Redisson就是使用watch dog解决了「锁过期释放,业务没执行完」问题。

加锁机制:

一个客户端A要加锁,它首先会根据hash节点选择一台机器,这里注意,仅仅只是选择一台机器。紧接着就会发送一段lua脚本到redis上,比如加锁的那个锁key就是"mylock",并且设置的时间是30秒,30秒后,mylock锁就会被释放

锁互斥机制:

如果这个时候客户端B来加锁,它也会会根据hash节点选择一台机器,然后执行了同样的一段lua脚本。
它首先回来判断"exists mylock"这个锁存在吗?如果存在,则B会获得一个数字,这个数字就是mylock这个锁的剩余生存时间,此时客户端B就会进入到一个while循环,不停的尝试加锁

watch dog自动延期机制:

客户端A加锁的锁key默认生存时间只有30秒,如果超过了30秒,客户端A还想一直持有这把锁,怎么办?其实只要客户端A一旦加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果客户端A还持有锁key,那么就会不断的延长锁key的生存时间

可重入加锁机制:

当客户端A获得mylock锁时,里面会有一个hash结构的数据:

mylock:{"8743c9c0-4907-0795-87fd-6c719a6b4586:1":1}

"8743c9c0-4907-0795-87fd-6c719a6b4586:1"就是代表客户端A,数字1就是代表这个客户端加锁了一次如果客户端A还想要持有锁mylock,那么这个1就会变成2,依次累加

释放锁机制:

如果发现加锁次数变为0了,那么说明这个客户端不再持有锁了,客户端B就可以加锁了

https://huaweicloud.csdn.net/637eeee1df016f70ae4c9eac.html

redisson最强大的地方就是提供了分布式特性的常用工具类。使得原本作为协调单机多线程并发程序的并发程序的工具包获得了协调分布式多级多线程并发系统的能力,降低了程序员在分布式环境下解决分布式问题的难度。

二  案例代码

2.1 工程搭建

1.工程结构

2.pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.10</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.atguigu</groupId><artifactId>distributed-lock</artifactId><version>0.0.1-SNAPSHOT</version><name>distributed-lock</name><description>Demo project for Spring Boot</description><properties><java.version>1.8</java.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><!--SpringBoot与Redis整合依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!-- redisson 分布式锁--><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.11.2</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.7.5</version></plugin></plugins></build></project>

2.2 redis服务启动

1.启动

2.设置

2.3 可重入锁

1.概述

基于 Redis Redisson 分布式可重入锁 RLock Java 对象实现了 java.util.concurrent.locks.Lock
接口。
如果负责储存这个分布式锁的 Redisson 节点宕机以后,而且这个锁正好处于锁住的状态
时,这个锁会出现锁死的状态。为了避免这种情况的发生, Redisson 内部提供了一个监控锁的看门狗, 它的作用是在Redisson 实例被关闭前,不断的延长锁的有效期。默认情况下,看门狗检查锁的超时时间是30 秒钟,也可以通过修改 Config.lockWatchdogTimeout 来另行指定。
RLock 对象完全符合 Java Lock 规范。也就是说 只有拥有锁的进程才能解锁,其他进程解锁则会抛出 IllegalMonitorStateException 错误。
另外 Redisson 还通过加锁的方法 提供了 leaseTime 的参数来指定加锁的时间 。超过这个时间后锁便自动解开了。

2.核心代码截图

 3.核心代码

 @GetMapping("stock/rt")public String decuceRt(){RLock lock=this.redissonClient.getLock("my-rt");lock.lock();try {//1.查询库存信息String stock = redisTemplate.opsForValue().get("stock").toString();// 2.判断库存是否充足if (stock != null && stock.length() > 0) {Integer st = Integer.valueOf(stock);if (st > 0) {//3.减库存操作redisTemplate.opsForValue().set("stock", String.valueOf(--st));}}}finally {lock.unlock();}return "ok!!!";}

4.测试

5.查看redis

127.0.0.1:6379> get stock
"\"49\""
 

2.4 公平锁

1.概念

基于 Redis Redisson 分布式可重入公平锁也是实现了 java.util.concurrent.locks.Lock 接口的一
RLock 对象。
它保证了当多个Redisson 客户端线程同时请求加锁时,优先分配给先发出请求的线程。所有请求线程会在一个队列中排队,当某个线程出现宕机时,Redisson 会等待 5 秒后继续下一个线程,也就是说如果前面有 5 个线程都处于等待状态,那么后面的线程会等待至少25 秒。
2.代码

 3.代码

@GetMapping("stock/fair")public String decuceFairLock(){RLock lock=this.redissonClient.getFairLock("myFairLock");lock.lock();try {//1.查询库存信息String stock = redisTemplate.opsForValue().get("stockfair").toString();// 2.判断库存是否充足if (stock != null && stock.length() > 0) {Integer st = Integer.valueOf(stock);if (st > 0) {//3.减库存操作redisTemplate.opsForValue().set("stockfair", String.valueOf(--st));}}try {TimeUnit.MILLISECONDS.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}}finally {lock.unlock();}return "ok123!!!";}
3.设置redis
127.0.0.1:6379> get stockfair 
"100"
 
4.访问

 5.查看

127.0.0.1:6379> get stockfair 
"\"99\""
127.0.0.1:6379> 

2.5 信号量

1.概述

基于 Redis Redisson 的分布式信号量( Semaphore Java 对象 RSemaphore 采用了与
java.util.concurrent.Semaphore 相似的接口和用法。
2.代码
@GetMapping("stock/sp")public String testsp(){RSemaphore lock=this.redissonClient.getSemaphore("sp");lock.trySetPermits(3);try {try {lock.acquire();this.redisTemplate.opsForList().rightPush("log","10086开始处理业务了"+Thread.currentThread().getName());TimeUnit.SECONDS.sleep(10+new Random().nextInt(10));this.redisTemplate.opsForList().rightPush("log","10086处理完成业务逻辑,释放资源======"+Thread.currentThread().getName());lock.release();} catch (InterruptedException e) {e.printStackTrace();}}finally {}return "信号量!!!";}

3.测试

 4.查看redis

2.6 闭锁

1.概念

基于 Redisson Redisson 分布式闭锁( CountDownLatch Java 对象 RCountDownLatch 采用了与
java.util.concurrent.CountDownLatch 相似的接口和用法。
2.

代码

@GetMapping("stock/suo")public String testsuo(){RCountDownLatch cd1=this.redissonClient.getCountDownLatch("cd1");cd1.trySetCount(3);System.out.println("进入 lock 之中喽。。。。。。");try {cd1.await();}catch (Exception e){e.printStackTrace();}return "cd lock!!!";}@GetMapping("stock/sf")public String testsf(){RCountDownLatch cd1=this.redissonClient.getCountDownLatch("cd1");try {cd1.countDown();System.out.println("执行 countdown---。。。。。");}catch (Exception e){e.printStackTrace();}return "cd unlock!!!";}

3.测试

这个接口请求3次,countdown变为0

 这个接口才能请求完成。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/18276.html

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

相关文章

各种好看的css效果收集

CSS动画特效-多种方案实现CSS光束扫过&#xff0c;扫光特效&#xff0c;ae文字过光效果&#xff0c;光效移动效果 一个集合180种免费的线性渐变网站&#xff0c;可在任何网站使用您不仅可以复制渐变的原生CSS颜色代码&#xff0c;还可以查看下载每个优质的渐变图片。 链接&…

第二课:Figma 界面认识

创建文件 进入 Figma 后&#xff0c;可以查看最近浏览的内容&#xff0c;官方也推荐了一些基础的项目&#xff0c;点击右上角 Design file&#xff08;设计文件&#xff09;即可创建项目&#xff1b; 注&#xff1a;网页版和本地版界面样式布局一致。 创建画布 点击左上画框…

C++_简单模拟实现string的基本结构

C中&#xff0c;string早于STL问世。使用string中的构造函数可以实现对string类型的字符串的一系列操作。 今天来模拟C中的string的基本结构。注意仅仅是简单模拟&#xff0c;string内部结构其实非常复杂&#xff0c;并且不同版本的IDEstring的内部结构也不尽相同。尽管有所不…

FLAC格式如何转换为MP3?分享三种方法!

在数字音乐的世界中&#xff0c;FLAC和MP3是两种常见的音频格式。FLAC (Free Lossless Audio Codec)提供无损的音质&#xff0c;但文件大小较大。而MP3文件较小&#xff0c;更易于传输和保存&#xff0c;但可能牺牲一些音质。如果你想将FLAC音频转换成MP3格式&#xff0c;本文将…

java版本企业电子招标采购系统源码Spring Cloud + Spring Boot +二次开发

java版本企业电子招标采购系统源码Spring Cloud Spring Boot 二次开发 一、立项管理 1、招标立项申请 功能点&#xff1a;招标类项目立项申请入口&#xff0c;用户可以保存为草稿&#xff0c;提交。 2、非招标立项申请 功能点&#xff1a;非招标立项申请入口、用户可以保存为草…

数学建模学习之简单设备分配问题

简单的设备分配问题 某公司新购置了某种设备 6台&#xff0c;欲分配给下属的4 个企业&#xff0c;已知各企业获得这种设备后年创利润如表 1.1 所示&#xff0c;单位为千万元。问应如何分配这些设备能使年创总利润最大&#xff0c;最大利润是多少? 表1.1的数据为&#xff1a; 对…

MYSQL学习第一天

1.创建数据库&#xff0c;删除数据库&#xff0c;查询创建数据的语句&#xff0c;使用数据库&#xff0c;查询当前默认的数据库以及使用的编码方式校验规则 1.1 创建数据库 create database db_name; 1.2 使用数据库 use db_name; 1.3 查询当前使用的数据库 select datab…

计讯物联网关型水利遥测终端机TY910确保闸站自动化监测长效运行

闸站是我国水利建设工程的重要组成部分&#xff0c;具备调度水源、防洪排涝、灌溉等能力&#xff0c;在农业、水路运输、养殖业等行业领域起着关键作用&#xff0c;进而解决区域水资源不均衡的问题&#xff0c;促进水资源多方面的利用。当前&#xff0c;我国闸站存在数量多、分…

第三次CCF计算机软件能力认证

第一题&#xff1a;门禁系统 涛涛最近要负责图书馆的管理工作&#xff0c;需要记录下每天读者的到访情况。 每位读者有一个编号&#xff0c;每条记录用读者的编号来表示。 给出读者的来访记录&#xff0c;请问每一条记录中的读者是第几次出现。 输入格式 输入的第一行包含一个整…

回归预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络多输入单输出回归预测

回归预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现WOA-CNN-BiLSTM鲸鱼算法优化卷积双向长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计学习总结参考资料 预测效果 基本介…

尚硅谷Docker实战教程-笔记12【高级篇,Docker-compose容器编排】

尚硅谷大数据技术-教程-学习路线-笔记汇总表【课程资料下载】视频地址&#xff1a;尚硅谷Docker实战教程&#xff08;docker教程天花板&#xff09;_哔哩哔哩_bilibili 尚硅谷Docker实战教程-笔记01【基础篇&#xff0c;Docker理念简介、官网介绍、平台入门图解、平台架构图解】…

使用Word轻松实现PDF转Word

以前WPS还能通过每天打卡白嫖会员&#xff0c;最近不行了&#xff0c;害&#xff0c;羊毛没了 现在重新回归Word&#xff0c;利用Word就可以将PDF转化为Word 一、通过Word新建一个Word文档并打开 二、点击 文件 —> 打开 三、浏览&#xff0c;找到要转的PDF 四、点击确定&…