RedisTemplate实现setnx分布式锁
redis工具类
`package com.ttsx.activity.item.services.utils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
/**
@ClassName :RedisUtils
@Description:redis工具
@Author :s30510
@Date :Created in 下午9:55 2022/7/17
@Modified By:
@Version:
/
@Slf4j
@Component
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
/*- lua 脚本
*/
public static final String SETNX_SCRIPT = "return redis.call('setnx',KEYS[1], ARGV[1])";
/**
- redis实现分布式锁
- @param key
- @return
*/
public boolean setNx(String key,int time) {
//自定义脚本
DefaultRedisScript script = new DefaultRedisScript<>(SETNX_SCRIPT, List.class);
//执行脚本,传入参数,由于value没啥用,这里随便写死的"1"
List rst = (List) redisTemplate.execute(script, Collections.singletonList(key), "1");
//返回1,表示设置成功,拿到锁
if(rst.get(0) == 1){
//log.info(key+"成功拿到锁");
//设置过期时间
expire(key,time);
//log.info(key+"已成功设置过期时间:"+time +" 秒");
return true;
}else{
long expire = getExpire(key);
//log.info(key+"未拿到到锁,还有"+expire+"释放");
return false;
}
}
/**
- 指定缓存失效时间
- @param key 键
- @param time 时间(秒)
- @return
*/
public void expire(String key, long time) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
/**
- 根据key 获取过期时间
- @param key 键 不能为null
- @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
- 删除缓存
- @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete((Collection) CollectionUtils.arrayToList(key));
}
}
}
- lua 脚本
}`
例子:

过期时间是为了防止死锁,当业务执行完毕,删除key释放锁
RedisTemplate实现setnx分布式锁的更多相关文章
- redis setnx 分布式锁
private final String RedisLockKey = "RedLock"; private final long altTimeout = 1 * 60 * 60 ...
- java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购
此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...
- RedisTemplate实现redis分布式锁
RedisLockUtil.java package com.meeno.inner.oa.common.redis; import lombok.extern.slf4j.Slf4j; import ...
- Redis 分布式锁(一)
前言 本文力争以最简单的语言,以博主自己对分布式锁的理解,按照自己的语言来描述分布式锁的概念.作用.原理.实现.如有错误,还请各位大佬海涵,恳请指正.分布式锁分两篇来讲解,本篇讲解客户端,下一篇讲解r ...
- 扩展redisTemplate实现分布式锁
原文:https://blog.csdn.net/qq1010267837/article/details/79697572 依赖jar包 compile group: 'redis.clients' ...
- Redis分布式锁,基于StringRedisTemplate和基于Lettuce实现setNx
使用redis分布式锁,来确保多个服务对共享数据操作的唯一性一般来说有StringRedisTemplate和RedisTemplate两种redis操作模板. 根据key-value的类型决定使用哪 ...
- Redis分布式锁—SETNX+Lua脚本实现篇
前言 平时的工作中,由于生产环境中的项目是需要部署在多台服务器中的,所以经常会面临解决分布式场景下数据一致性的问题,那么就需要引入分布式锁来解决这一问题. 针对分布式锁的实现,目前比较常用的就如下几种 ...
- Redis_redis分布式锁-SETNX
因业务需要使用了redis的SETNX来实现分布式锁. 描述:Redis有一系列的命令,特点是以NX结尾,NX是Not eXists的缩写,如SETNX命令就应该理解为:SET if Not eXis ...
- Redis setNX 实现分布式锁(重复数据插入可用其来实现排他锁)
使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其实现方法. SETNX命令简介 命令格式 SETNX key value 将 key 的值设为 value,当且仅当 key 不存在. 若 ...
- 使用Redis SETNX 命令实现分布式锁
基于setnx和getset http://blog.csdn.net/lihao21/article/details/49104695 使用Redis的 SETNX 命令可以实现分布式锁,下文介绍其 ...
随机推荐
- Netty SSL双向验证
一· 快速命令 1.生成ca证书 openssl req -new -x509 -keyout ca.key -out ca.crt -days 36500在本目录得到 ca.key 和 ca.crt ...
- mapstruct坑:Internal error in the mapping processor: java.lang.NullPointerException at org.mapstruct.
错误描述 项目中如果使用了mapstruct框架,在使用Idea新版本后,启动会报错! Internal error in the mapping processor: java.lang.NullP ...
- 操作系统messages文件位置更改
问题现象 在遇到一个问题的时候需要查看操作系统的日志,但是到操作系统上的 /var/log/messages 文件中发现该文件已经很久没有刷新过了. 这个系统之前是做过安全加固的,我怀疑它改过操作系统 ...
- Qt编写安防视频监控系统68-兼容Qt4到Qt6
一.前言 为了从Qt4.7兼容到Qt6.2及后续版本,着实花了不少精力,前提也是对自定义控件大全和各种跨平台的轮子组件全部做成了兼容Qt4到Qt6,这样只剩下UI这块需要兼容就好办多了,各个击破战略, ...
- 关于Qt选择qml还是widget的深度思考
在Qt界始终有两大阵营产生激烈的纷争,那就是选用qml还是widget好,大量初学者也会问这个问题,有以下几点总结. widget属于传统界面开发,和VB/VC/Delphi等拖曳控件开发类似,走CP ...
- golang两个协程交替打印出1-100
基于channel实现的,两个协程交替打印出1-100 package main import ( "fmt" "sync" ) var ( toOdd = m ...
- springcloud eureka原理和机制
公司的注册中心使用的是Eureka,之前使用过ZooKeeper,大致原理应该差不多,具体细节需要进一步学习,正好之前在腾讯云开发者社区看到一篇讲得很不错的文章,转载过来方便查看. 简介 在微服务架构 ...
- 基于.NET8.0实现RabbbitMQ的Publish/Subscribe发布订阅以及死信队列
[前言] RabbitMQ提供了五种消息模型,分别是简单模型.工作队列模型.发布/订阅模型.路由模型和主题模型. 简单模型(Simple):在这种模式下,一个生产者将消息发送到一个队列,只有一个 ...
- nginx 简单实践:静态资源部署、URL 重写【nginx 实践系列之一】
〇.前言 本文为 nginx 简单实践系列文章之一,主要简单实践了两个内容:静态资源部署.重写,仅供参考. 关于 Nginx 基础,以及安装和配置详解,可以参考博主过往文章: https://www. ...
- c# 通过注册表判断有没有安装某个软件
private bool checkHasInstalledSoftWare(string displayName) { Microsoft.Win32.RegistryKey uninstallNo ...