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://xiahunao.cn/news/2815750.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

K8S存储卷与PV,PVC

一、前言 Kubernetes&#xff08;K8s&#xff09;中的存储卷是用于在容器之间共享数据的一种机制。存储卷可以在多个Pod之间共享数据&#xff0c;并且可以保持数据的持久性&#xff0c;即使Pod被重新调度或者删除&#xff0c;数据也不会丢失。 Kubernetes支持多种类型的存储卷…

【大数据架构(2)】kappa架构介绍

文章目录 一. Kappa架构1. Speed Layer (Stream Layer) - The Foundation of Kappa Architecture2. Stream Processing: The Heart of Kappa Architecture 二. Benefits of Kappa and Streaming Architecture1. Simplicity and Streamlined Pipeline2. High-Throughput Process…

数据服务安全的重要性

数据服务安全在当今信息化社会显得尤为重要。随着大数据、云计算、人工智能等技术的飞速发展&#xff0c;数据已经成为企业和组织的核心资产&#xff0c;数据服务安全也面临着前所未有的挑战。本文将从数据服务安全的重要性、常见威胁、防护策略以及未来发展趋势等方面进行探讨…

ROS 2基础概念#1:计算图(Compute Graph)| ROS 2学习笔记

在ROS中&#xff0c;计算图&#xff08;ROS Compute Graph&#xff09;是一个核心概念&#xff0c;它描述了ROS节点之间的数据流动和通信方式。它不仅仅是一个通信网络&#xff0c;它也反映了ROS设计哲学的核心——灵活性、模块化和可重用性。通过细致探讨计算图的高级特性和实…

2024年小程序云开发CMS内容管理无法使用,无法同步内容模型到云开发数据库的解决方案,回退老版本CMS内容管理的最新方法

一&#xff0c;问题描述 最近越来越多的同学找石头哥&#xff0c;说cms用不了&#xff0c;其实是小程序官方最近又搞大动作了&#xff0c;偷偷的升级的云开发cms&#xff08;内容管理&#xff09;以下都称cms&#xff0c;不升级不要紧&#xff0c;这一升级&#xff0c;就导致我…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之FlowItem容器组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之FlowItem容器组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、FlowItem组件 子组件 可以包含子组件。 接口 FlowItem() 使用该接口来…

Android14之解决编译报错:bazel: no such file or directory(一百八十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a;多媒…

Stable Diffusion WebUI 图库浏览器插件:浏览器以前生成的图片

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 大家好&#xff0c;我是水滴~~ 本文介绍的插件叫图库浏览器&#xff0c;是一个用于浏览器以前生成的图片信息的插件。本文将介绍该插件的安装和使用&#xff0c;希望能够对你有所帮助。 文章…

GitHub宣布GitHub Copilot Enterprise的全面发布;使用Python与Gemma和MongoDB构建RAG系统的全过程

&#x1f989; AI新闻 &#x1f680; GitHub宣布GitHub Copilot Enterprise的全面发布 摘要&#xff1a;GitHub Copilot Enterprise是一款基于OpenAI的GPT-4模型的代码助手&#xff0c;它结合了十多年的真实、安全可靠的代码数据进行开发。该工具可以通过文本提示来获取、审核…

JavaEE进阶(7)Spring Boot 日志(概述、用途、使用:打印日志,框架介绍,SLF4J 框架介绍、更简单的日志输出)

接上次博客&#xff1a;JavaEE进阶&#xff08;6&#xff09;SpringBoot 配置文件&#xff08;作用、格式、properties配置文件说明、yml配置文件说明、验证码案例&#xff09;-CSDN博客 目录 日志概述 日志的用途 日志使用 打印日志 在程序中获取日志对象 使用日志对象…

练习 3 Web [ACTF2020 新生赛]Upload

[ACTF2020 新生赛]Upload1 中间有上传文件的地方&#xff0c;试一下一句话木马 txt 不让传txt 另存为tlyjpg&#xff0c;木马文件上传成功 给出了存放目录&#xff1a; Upload Success! Look here~ ./uplo4d/06a9d80f64fded1e542a95e6d530c70a.jpg 下一步尝试改木马文件后缀…

Python的自然语言处理库NLTK介绍

NLTK&#xff08;Natural Language Toolkit&#xff09;简介 NLTK是Python中一个领先的自然语言处理&#xff08;NLP&#xff09;库&#xff0c;它提供了文本处理的基础设施&#xff0c;包括分词&#xff08;tokenization&#xff09;、词性标注&#xff08;part-of-speech tag…

云计算与边缘计算:有何不同?

公共云计算平台可以帮助企业充分利用全球服务器来增强其私有数据中心。这使得基础设施能够扩展到任何位置&#xff0c;并有助于计算资源的灵活扩展。混合公共-私有云为企业计算应用程序提供了强大的灵活性、价值和安全性。 然而&#xff0c;随着分布在全球各地的实时人工智能应…

亚马逊自养号测评:如何安全搭建环境,有效规避风险

要在亚马逊上进行自养号测评&#xff0c;构建一个真实的国外环境至关重要。这包括模拟国外的服务器、IP地址、浏览器环境&#xff0c;甚至支付方式&#xff0c;以创建一个完整的国际操作环境。这样的环境能让我们自由注册、养号并下单&#xff0c;确保所有操作均符合国际规范。…

十三、Qt多线程与线程安全

一、多线程程序 QThread类提供了管理线程的方法&#xff1a;一个对象管理一个线程一般从QThread继承一个自定义类&#xff0c;重载run函数 1、实现程序 &#xff08;1&#xff09;创建项目&#xff0c;基于QDialog &#xff08;2&#xff09;添加类&#xff0c;修改基于QThr…

微软广告和网络服务CEO承认OpenAI的Sora将加入Copilot,但需要一些时间

事情的起因是一名网友询问 Sora 是否会加入 Copilot&#xff0c;微软广告和网络服务CEO首席执行官——Mikhail Parakhin 回应说&#xff1a;“最终&#xff0c;但这需要时间。”毕竟投了几十个亿美金进去&#xff0c;不亏是金主爸爸。 图为Mikhail Parakhin Sora是OpenAI开发的…

2024年阿里云2核4G配置服务器测评_ECS和轻量性能测评

阿里云2核4G服务器多少钱一年&#xff1f;2核4G服务器1个月费用多少&#xff1f;2核4G服务器30元3个月、85元一年&#xff0c;轻量应用服务器2核4G4M带宽165元一年&#xff0c;企业用户2核4G5M带宽199元一年。本文阿里云服务器网整理的2核4G参加活动的主机是ECS经济型e实例和u1…

nginx 日志,压缩,https功能介绍

一&#xff0c; 自定义访问日志 &#xff08;一&#xff09;日志位置存放 1&#xff0c;格式 2&#xff0c; 级别 level: debug, info, notice, warn, error, crit, alert, emerg 3&#xff0c;示例 服务机定义 错误日志存放位置 客户机错误访问 查看错误日志 4&#xff…

级联选择el-cascader可以选中任意一项

最近遇到一个需求,就是级联选择用的el-cascader组件,然后用户可以选中第一级,或者说可以选中第二级,或者说可以选中第三级,如下图所示: 代码如下: 单独选择任意一项须设置属性 checkStrictly为true ,绑定的是其 id ,popper-class设置自定义类名为popperClass,如下图…

only office-用着确实很省心

小程一言 最近一直在使用各种办公软件进行学习笔记整理&#xff0c;但是在使用过程中&#xff0c;总感觉不是自己想要的一款软件&#xff0c;想要一款真正懂自己的软件&#xff0c;是一个选择的过程。最近在网上闲逛发现一款宝藏软件&#xff0c;好奇心驱使我去进行适用&#…