redis实现分布式锁,lua脚本实现上锁原子操作

news/2024/7/23 15:09:20 标签: redis, lua, 分布式, 分布式锁
  • 基础操作
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 使用Lua脚本的好处
    1、 一次性发送多个命令,减少网络开销。(是多个reids命令的集合,不用每次都去建立连接)
    2、原子性 (redis会将这个lua脚本认为是一个整体去执行,不会被打断,所以保证原子性)
    3、lua 文件复用 (命令非常多,可以放在一个文件中,这样其他的redis也可以调用,使其复用)

  • 基本用法

127.0.0.1:6379> eval "return 'hello world'" 0
"hello world"
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> eval "return redis.call('set',KEYS[1],ARGV[1])" 1 HZ 2222
OK
127.0.0.1:6379> keys *
1) "HZ"
127.0.0.1:6379> get hz
(nil)
127.0.0.1:6379> get HZ
"2222"
127.0.0.1:6379> 
  • demo
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class RedisUtil {

    /**
     * 获取锁的value,判断是否等于期待的value,满足的话,则删除该锁,并返回1;否则直接返回-1。
     */
    private static final DefaultRedisScript<Long> UNLOCK_LUA_SCRIPT = new DefaultRedisScript<>(
            "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return -1 end", Long.class
    );

    @Autowired
    private StringRedisTemplate redisTemplate;

	/**
     * 上锁
     * @param key			键
     * @param value			值
     * @param expireTime	失效时间
     * @param timeUnit		时间单位
     * @return
     */
    public boolean tryLockTime(String key, String value, long expireTime, TimeUnit timeUnit) {
        Boolean flag = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, timeUnit);
        if (flag == null || !flag) {
            log.error("申请锁(" + key + "," + value + ")失败");
            return false;
        }
        return true;
    }

    /**
     * 解锁
     *
     * @param key   键
     * @param value 值
     */
    public void unLockTime(String key, String value) {
        Long result = redisTemplate.execute(UNLOCK_LUA_SCRIPT, Collections.singletonList(key), value);
        if (result == -1) {
            log.error("释放锁(" + key + "," + value + ")失败,该锁不存在或锁已经过期");
        }
    }
}

  • 上锁
Boolean flag = redisUtil.tryLockTime("key", "value", 180, TimeUnit.SECONDS);
  • 解锁
redisUtil.unLockTime("key", "value");

http://www.niftyadmin.cn/n/1691215.html

相关文章

冷却水的循环方式有哪几种_工业循环冷却水系统处理的重要性

循环水的使用及水处理的重要性用水来冷却工艺介质的系统&#xff0c;我们称作冷却水系统&#xff0c;通常可分为以下两种类型&#xff1a;直流冷却水系统和循环冷却水系统。其中&#xff0c;循环冷却水系统目前已被广泛地应用于各行各业之中&#xff0c;比如&#xff0c;石油化…

redis执行lua脚本

原文&#xff1a;https://blog.csdn.net/m0_67402125/article/details/123792116 语法格式 语法: eval script numkeys keys args 参数: eval — redis提供解析lua脚本的命令 script — lua脚本 numkeys — 指定键名参数集(keys)的个数 keys — 键名参数集&#xff0c;通…

vue 实现扫条形码与二维码 H5 兼容 苹果IOS

1、注意 vue-qrcode-reader采用摄像头解析&#xff0c;浏览器为了安全&#xff0c;只有https协议下或者本地localhost可访问摄像头&#xff0c;所以代码需要部署所在的服务器需要https 2、具体实现① 安装插件 npm install --save vue-qrcode-reader创建组件 <template&g…

redis序列化设置,redis键、值...乱码

使用redis存值的时候发现值有乱码的情况&#xff0c;这是因为RedisTemplate可以接收任意Object作为值写入Redis&#xff0c;只不过写入前会把Object序列化为字节形式&#xff0c;默认是采用JDK序列化RedisTemplate提供了四种序列化方式如果不指定序列化方式会默认采用JDK序列化…

对div等容器中的文字进行限制,超出3行的显示省略号···

overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3;

二维随机变量期望公式_【统计学进阶知识(一)】深入理解Beta分布:从定义到公式推导...

读者知识背景&#xff1a;微积分&#xff0c;概率统计目录(1) Beta分布及其函数公式推导(2) Beta 函数和 Gamma 函数的关系(3) Beta 分布的期望与方差(4) Beta分布与二项分布的关系(5) Beta分布与均匀分布的关系Beta分布是一种连续型概率密度分布&#xff0c;表示为 &#xff0…

java对比两张图片是否一致_用python实现对比两张图片的不同

from PIL import Image from PIL import ImageChops def compare_images(path_one, path_two, diff_save_location):"""比较图片&#xff0c;如果有不同则生成展示不同的图片参数一: path_one: 第一张图片的路径参数二: path_two: 第二张图片的路径参数三: dif…

存储过程 while is null_C++线性表的链式存储结构

为了解决顺序存储不足&#xff1a;用线性表另外一种结构-链式存储。在顺序存储结构(数组描述)中&#xff0c;元素的地址是由数学公式决定的&#xff0c;而在链式储存结构中&#xff0c;元素的地址是随机分布的&#xff0c;每个元素都有一个明确的指针指向线性表的下一个元素的位…