redis中的分布式锁(setIfAbsent)(expire)

目录

应用场景

代码实例1:

代码实例2:

setIfAbsent:

expire:

举例说明:

代码实例3:

代码实例4:


还是一个同事问的一个问题,然后闲着没事就记录下来了。多人操作同一个保单,会出现数据不一致,所以呢,就准备为此单子加一个锁,所以就有了下面的代码。分享给大家

分布式锁的定义大家基本都很了解了,具体就是当需要在分布式环境中保证资源的互斥访问或一致性时,就可以考虑使用分布式锁。但需要注意的是,分布式锁虽然可以解决问题,但也会带来一定的性能开销和复杂度,因此在使用时需要权衡系统的性能和可维护性,以及使用分布式锁所带来的成本和风险。

应用场景

  1. 发任务调度:在分布式系统中,当需要对某个任务进行调度时,如果多个节点同时发起任务调度请求,可能会导致任务被多次执行。这时可以使用分布式锁来确保只有一个节点能够成功获取到任务调度的锁,从而避免任务的重复执行。
  2. 分布式事务:在分布式事务中,需要保证不同节点对共享资源的访问是互斥的,以防止数据不一致的问题。分布式锁可以用来保证在事务执行过程中,各个节点之间对共享资源的访问是互斥的。
  3. 分布式缓存:在分布式缓存中,如果多个节点同时对缓存进行访问和修改,可能会导致缓存中的数据不一致。这时可以使用分布式锁来确保各个节点对缓存的访问是互斥的。
  4. 购买限制:在电商等场景中,如果需要对某个商品的购买数量进行限制,当多个用户同时发起购买请求时,可以使用分布式锁来确保只有一个用户能够成功获取到购买锁,从而避免超卖等问题。

代码实例1:

redisTemplate.opsForValue().setIfAbsent("redisLock", uuid, 1000, TimeUnit.SECONDS);

这段代码是使用Spring Data Redis的RedisTemplate来执行一个Redis操作。具体来说,它尝试在Redis中设置一个键值对,但仅当该键不存在时。

详细解释如下:

  • "ruleRefreshLock":这是要设置的Redis键。
  • uuid:这是要设置的Redis值。
  • 1000:这是值的过期时间,单位是毫秒。
  • TimeUnit.SECONDS:这是过期时间的单位,这里是秒。

setIfAbsent方法的行为如下:

  • 如果键"ruleRefreshLock"在Redis中不存在,那么它会设置这个键的值为uuid,并给这个键设置一个1000秒的过期时间。此时,setIfAbsent方法返回true
  • 如果键"ruleRefreshLock"在Redis中已经存在,那么它不会做任何操作,并且setIfAbsent方法返回false

这个方法通常用于实现分布式锁。在这个例子中,你可能想要确保只有一个实例或线程能够获取到"ruleRefreshLock"这个锁。如果锁已经被其他实例或线程获取(即键已经存在),那么当前实例或线程就不会再尝试获取锁。如果锁未被获取(即键不存在),那么当前实例或线程就会获取锁,并设置一个过期时间以确保锁最终会被释放。

代码实例2:

设置KEY值过期时间

//假设 lockName 是你的锁的名称,expireTime 是你希望锁持续的时间(以分钟为单位)
redisTemplate.expire(lockName, expireTime, TimeUnit.MINUTES);

这段代码是使用 RedisTemplate 来设置 Redis 中某个键的过期时间。这与之前的 setIfAbsent 操作有所不同,主要区别如下:

setIfAbsent

  • 目的:尝试设置一个键值对,但仅当该键不存在时。
  • 返回值:如果键原本不存在且成功设置了键值对,返回 true;如果键已经存在,则不做任何操作并返回 false
  • 用途:通常用于实现分布式锁或其他需要原子性设置键值对的场景。

expire

  • 目的:为已存在的键设置或更新其过期时间。
  • 返回值:如果键存在,则成功设置或更新过期时间并返回 true;如果键不存在,则不进行任何操作并返回 false
  • 用途:通常用于确保存储在 Redis 中的数据在一段时间后被自动删除,以避免内存无限制增长。

举例说明:

假设你已经有了一个名为 lockName 的锁,并且这个锁已经被某个实例获取(即该键在 Redis 中已经存在)。你想让这个锁在一段时间后自动释放,那么你可以使用 expire 方法来设置锁的过期时间。

代码实例3:

redis版本        spring-data-redis-2.7.10.jar

@Slf4j
@Component
public class redisSchedule implements SchedulingConfigurer  {@Value("${rule.limit.cron}")private String cron;@Value("${schedule.rule}")private String scheduleRule;@Autowiredprivate StringRedisTemplate redisTemplate;@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {taskRegistrar.addCronTask(() -> {// 分布式锁,集群环境只允许一台服务修改定时任务String uuid = UUID.randomUUID().toString();Boolean bool = redisTemplate.opsForValue().setIfAbsent("redisLock", uuid, 1000, TimeUnit.SECONDS);try {if (bool) {//逻辑代码}} catch (Exception e) {log.error(e.getMessage());} finally {//  释放锁,先比对自己锁的值是否相等,相等则为自己的锁String script = "if redis.call('get',KEYS[1]) == ARGV[1] then return redis.call('del',KEYS[1]) else return 0 end";redisTemplate.execute(new DefaultRedisScript<Long>(script, Long.class), Arrays.asList("redisLock"), uuid);}}, cron);}
}

代码实例4:

redis版本        spring-data-redis-1.8.0.RELEASE.jar

//锁的过期时间,默认为5分钟
private Long expireTime = 5L;try {//多个执行任务去获得锁,如果没有获取证明还有任务在执行中,那么将不再执行任务Boolean isLock = redisTemplate.opsForValue().setIfAbsent(lockName, "lock");if (isLock){//获取到锁,那么设置过期时间,防止死锁this.redisTemplate.expire(lockName, expireTime, TimeUnit.MINUTES);//逻辑代码}else {logger.info("任务执行锁定失败,Lock被占用,当前分片:=====");throw new Exception("任务执行锁定失败");}} catch (Exception e) {e.printStackTrace();throw new Exception(e.getMessage());}

总结一下,setIfAbsent 用于在键不存在时设置键值对,并返回操作是否成功的布尔值;而 expire 用于设置或更新已存在键的过期时间,并返回操作是否成功的布尔值。这两个操作经常一起使用来实现分布式锁,其中 setIfAbsent 用于尝试获取锁,而 expire 用于设置锁的过期时间以确保锁最终会被释放。两种方式的用法看对应的应用场景来使用

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

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

相关文章

npm、cnpm、pnpm使用详细

简介&#xff1a; npm&#xff1a;npm&#xff08;Node Package Manager&#xff09;是Node.js的包管理工具&#xff0c;用于安装、更新、卸载Node.js的模块和包。它提供了一个命令行界面&#xff0c;使得开发者可以轻松地管理项目依赖。npm 是 nodejs 中的一部分&#xff0c;…

vue3+uniapp在微信小程序实现一个2048小游戏

一、效果展示 二、代码 <template><view class"page"><view class"top"><view class"score">得分:{{total}}</view><view class"time">用时:{{allTime}}s</view></view><view cl…

网络工程师笔记8

华为VRP系统 设备管理方式 web管理方式 命令行管理方式 修改命令&#xff1a;undo 基础配置命令

期货开户保证金保障市场正常运转

期货保证金是什么&#xff1f;在期货市场上&#xff0c;采取保证金交易制度&#xff0c;投资者只需按期货合约的价值&#xff0c;交一定比率少量资金即可参与期货合约买卖交易&#xff0c;这种资金就是期货保证金。期货保证金&#xff08;以下简称保证金〕按性质与作用的不同。…

记录SSM项目集成Spring Security 4.X版本 之 加密验证和记住我功能

目录 前言 一、用户登录密码加密认证 二、记住我功能 前言 本次笔记的记录是接SSM项目集成Spring Security 4.X版本 之 加入DWZ,J-UI框架实现登录和主页菜单显示-CSDN博客https://blog.csdn.net/u011529483/article/details/136255768?spm1001.2014.3001.5502 文章之后补…

神经网络结构——CNN、RNN、LSTM、Transformer !!

文章目录 前言 一、什么是CNN 网络结构 解决问题 工作原理 实际应用 二、什么是RNN 网络结构 解决问题 工作原理 应用场景 三、什么是LSTM 网络结构 解决问题 工作原理 应用场景 四、什么是Transformer 网络结构 解决问题 工作原理 BERT GPT 前言 本文将从什么是CNN&#xff1…

Redis的介绍与使用

文章目录 Redis简介安装RedisRedis常用命令全局命令String类型数据Hash哈希类型数据List列表类型数据Set集合类型数据SortedSet有序集合类型数据 一些选择题一些选择题 Redis简介 Redis是一款基于键值对的NoSQL数据库&#xff0c;它的值支持多种数据结构&#xff1a; 字符串(s…

代码随想录算法训练营第26天—回溯算法06 | ● *332.重新安排行程 ● *51. N皇后 ● *37. 解数独 ● 总结

*332.重新安排行程 https://programmercarl.com/0332.%E9%87%8D%E6%96%B0%E5%AE%89%E6%8E%92%E8%A1%8C%E7%A8%8B.html 考点 图论里的深度优先搜索&#xff08;本题使用回溯来解决&#xff09;这是一道hard题&#xff0c;一刷先放过去&#xff0c;二刷有精力再做 我的思路 无思…

【AI Agent系列】【MetaGPT多智能体学习】4. 基于MetaGPT的Team组件开发你的第一个智能体团队

本系列文章跟随《MetaGPT多智能体课程》&#xff08;https://github.com/datawhalechina/hugging-multi-agent&#xff09;&#xff0c;深入理解并实践多智能体系统的开发。 本文为该课程的第四章&#xff08;多智能体开发&#xff09;的第二篇笔记。主要是对MetaGPT中Team组件…

二叉搜索树题目:将有序数组转换为二叉搜索树

文章目录 题目标题和出处难度题目描述要求示例数据范围 解法思路和算法证明代码复杂度分析 题目 标题和出处 标题&#xff1a;将有序数组转换为二叉搜索树 出处&#xff1a;108. 将有序数组转换为二叉搜索树 难度 4 级 题目描述 要求 给定整数数组 nums \texttt{nums}…

力扣 第 125 场双周赛 解题报告 | 珂学家 | 树形DP + 组合数学

前言 整体评价 T4感觉有简单的方法&#xff0c;无奈树形DP一条路上走到黑了&#xff0c;这场还是有难度的。 T1. 超过阈值的最少操作数 I 思路: 模拟 class Solution {public int minOperations(int[] nums, int k) {return (int)Arrays.stream(nums).filter(x -> x <…

springboot230基于Spring Boot在线远程考试系统的设计与实现

在线远程考试系统设计与实现 摘 要 信息数据从传统到当代&#xff0c;是一直在变革当中&#xff0c;突如其来的互联网让传统的信息管理看到了革命性的曙光&#xff0c;因为传统信息管理从时效性&#xff0c;还是安全性&#xff0c;还是可操作性等各个方面来讲&#xff0c;遇到…

协议和序列化反序列化

“协议”和序列化反序列化 “协议”的概念&#xff1a; “协议”本身是一种约定俗成的东西&#xff0c;由通讯双方必须共同遵从的一组约定&#xff0c;因此我们一定要将这种约定用计算机语言表达出来&#xff0c;此时双方计算机才能识别约定的相关内容 我们把这个规矩叫做“…

今晚打老虎:用katalon解决接口/自动化测试拦路虎--参数化

不管是做接口测试还是做自动化测试&#xff0c;参数化肯定是一个绕不过去的坎。 因为我们要考虑到多个接口都使用相同参数的问题。所以&#xff0c;本文将讲述一下katalon是如何进行参数化的。 全局变量 右侧菜单栏中打开profile&#xff0c;点击default&#xff0c;打开之后…

【LeetCode】升级打怪之路 Day 11:栈的应用、单调栈

今日题目&#xff1a; Problem 1: 栈的应用 155. 最小栈 | LeetCode20. 有效的括号 | LeetCode150. 逆波兰表达式求值 | LeetCode Problem 2: 单调栈 496. 下一个更大元素 I739. 每日温度503. 下一个更大元素 II 目录 Problem 1&#xff1a;栈 - “先进后出”的应用LC 155. 最…

IO(Linux)

文件系统 前言1. 回顾关于C文件部分函数2. 一些文件知识的共识3. 相对路径4. fwrite中的\0 一、文件描述符fd1. 概念2. 系统调用① open 和 close② write③ read 和 lseek 3. 缺省打开的fd 二、重定向1. 原理2. 系统调用dup23. stdout和stderr的区别4. 进程替换和原来进程文件…

Linux笔记-3

软件安装 概述 在Linux中&#xff0c;软件安装分为3种方式&#xff1a;绿色安装(压缩包解压之后就能直接使用)&#xff0c;rpm安装(类似于Windows中的exe或者msi文件)&#xff0c;yum安装 RPM(Red Hat Package Manager)&#xff1a;红帽提供的软件包的管理工具。可以通过rpm命…

Github项目推荐-LightMirrors

项目地址 https://github.com/NoCLin/LightMirrors 项目简述 “LightMirrors是一个开源的缓存镜像站服务&#xff0c;用于加速软件包下载和镜像拉取。目前支持DockerHub、PyPI、PyTorch、NPM等镜像缓存服务。 当前项目仍处于早期阶段。”–来自项目说明。 也就是说&#xff…

vue中使用prettier

前言&#xff1a;prettier是一款有态度的代码格式化工具&#xff0c;它可以集成在IDE中&#xff0c;如VS Code、Web Storm等&#xff0c;也可以安装到我们开发的项目里面。本文主要讲解在Vue中集成prettier的过程&#xff0c;可以便于代码检测和格式化。 prettier官网 从官网的…

ardupilot 及PX4姿态误差计算算法对比分析

目录 文章目录 目录摘要1.APM姿态误差计算算法2.PX4姿态误差计算算法3.结论摘要 本节主要记录ardupilot 及PX4姿态误差计算算法差异对比过程,欢迎批评指正。 备注: 1.创作不易,有问题急时反馈 2.需要理解四元物理含义、叉乘及点乘含义、方向余弦矩阵含义、四元数乘法物理含…