基于 Redis + Lua 脚本实现分布式锁,确保操作的原子性

1.加锁的Lua脚本: lock.lua
--- -1 failed
--- 1 success

--- getLock key
local result = redis.call('setnx' , KEYS[1] , ARGV[1])
if result == 1 then
    --PEXPIRE:以毫秒的形式指定过期时间
    redis.call('pexpire' , KEYS[1] , 3600000)
else
    result = -1;
    -- 如果value相同,则认为是同一个线程的请求,则认为重入锁
    local value = redis.call('get' , KEYS[1])
    if (value == ARGV[1]) then
        result = 1;
        redis.call('pexpire' , KEYS[1] , 3600000)
    end
end
--  如果获取锁成功,则返回 1
return result
2.解锁的Lua脚本: unLock.lua
if redis.call('get', KEYS[1]) == ARGV[1]
    then
        return redis.call('del', KEYS[1])
    else
        return 0
end
3.将资源文件放在资源文件夹下

4.Java中调用lua脚本

1)获取文件方式

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;

/**
 * @Author: best_liu
 * @Description:
 * @Date Create in 14:04 2023/10/26
 * @Modified By:
 */
@Slf4j
@RestController
public class LuaLock {


    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping(value = "/getLock")
    public Long getLock() {
        DefaultRedisScript<Long> script = new DefaultRedisScript<Long>();
        script.setResultType(Long.class);
//        获取lua文件方式
        script.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/lock.lua")));
        
        Long execute = (Long) redisTemplate.execute(script, Arrays.asList("best_liu"),"best_liu20231026150600");
        return execute;
    }
}

2)lua字符串方式

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.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;

/**
 * @Author: best_liu
 * @Description:
 * @Date Create in 14:04 2023/10/26
 * @Modified By:
 */
@Slf4j
@RestController
public class LuaLock {


    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping(value = "/getLock")
    public Long getLock() {
        DefaultRedisScript<Long> script = new DefaultRedisScript<Long>();
        script.setResultType(Long.class);
//        获取lua文件方式
//        script.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/lock.lua")));
        String lua = "local result = redis.call('setnx' , KEYS[1] , ARGV[1])\n" +
                "if result == 1 then\n" +
                "    redis.call('pexpire' , KEYS[1] , 3600000)\n" +
                "else\n" +
                "    result = -1;\n" +
                "    local value = redis.call('get' , KEYS[1])\n" +
                "    if (value == ARGV[1]) then\n" +
                "        result = 1;\n" +
                "        redis.call('pexpire' , KEYS[1] , 3600000)\n" +
                "    end\n" +
                "end\n" +
                "return result";
        script.setScriptText(lua);
        Long execute = (Long) redisTemplate.execute(script, Arrays.asList("best_liu"),"best_liu20231026150600");
        return execute;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

数据清洗(data clean)

整理了下数据清洗的基本流程&#xff0c;异常值部分整理在了EDA中。

什么是简单网络管理协议(SNMP)

简单网络管理协议&#xff08;SNMP&#xff1a;Simple Network Management Protocol&#xff09;是由互联网工程任务组&#xff08;IETF&#xff1a;Internet Engineering Task Force &#xff09;定义的一套网络管理协议。该协议基于简单网关监视协议&#xff08;SGMP&#xf…

React中的Virtual DOM(看这一篇就够了)

文章目录 前言了解Virtual DOMreact创建虚拟dom的方式React Element虚拟dom的流程虚拟dom和真实dom的对比后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;react合集 &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌…

DevOps持续集成-Jenkins(3)

文章目录 DevOpsDevOps概述Jenkins实战3&#xff1a;实战1和实战2的加强版&#xff08;新增SonarQube和Harbor&#xff09;⭐环境准备⭐项目架构图对比Jenkins实战1和实战2&#xff0c;新增内容有哪些&#xff1f;SonarQube教程采用Docker安装SonarQube &#xff08;在Jenkins所…

生成树协议:监控 STP 端口和交换机

什么是生成树协议 生成树协议 &#xff08;STP&#xff09; 用于网络交换机&#xff0c;以防止循环和广播风暴。在局域网 &#xff08;LAN&#xff09; 中&#xff0c;两条或多条冗余路径可以连接到同一网段。当交换机或网桥从所有可用端口传输帧时&#xff0c;这些帧开始在网…

基于单片机设计的智能窗帘控制系统

一、前言 智能家居技术在近年来取得了巨大的发展&#xff0c;并逐渐成为人们日常生活中的一部分。智能家居系统带来了便利、舒适和高效的生活体验&#xff0c;拥有广泛的应用领域&#xff0c;其中之一就是智能窗帘控制系统。 传统窗帘需要手动操作&#xff0c;打开或关闭窗帘…

华硕天选1天选2天选3天选4天选air原厂预装出厂系统恢复安装教程方法

华硕天选1天选2天选3天选4天选air原厂预装出厂系统恢复安装教程方法 第一:自备原装swm/esd/wim/iso等格式系统文件&#xff0c;以上这几种格式文件安装恢复非常简单&#xff0c;使用PE工具即可完成恢复安装&#xff0c;还有一种安装方法就是华硕zip工厂恢复模式 1.首先需要自…

Adaptive AUTOSAR RTA-VRTE工具链介绍

ETAS Adaptive AUTOSAR RTA-VRTE是一种面向服务架构的中间件方案,提供了自适应AutoSAR平台,为应用层软件提供了运行环境. RTA-VRTE start kit的构建系统在主机VM内执行,可以创建AUTOSAR自适应应用程序并将其部署到一个或多个目标ECU虚拟机.

【VPX610】 青翼科技基于6U VPX总线架构的高性能实时信号处理平台

板卡概述 VPX610是一款基于6U VPX架构的高性能实时信号处理平台&#xff0c;该平台采用2片TI的KeyStone系列多核DSP TMS320C6678作为主处理单元&#xff0c;采用1片Xilinx的Virtex-7系列FPGA XC7VX690T作为协处理单元&#xff0c;具有2个FMC子卡接口&#xff0c;各个处理节点之…

linux-文件系统

目录 一、文件系统 1.分区 2.文件系统分类 3.文件系统创建工具 4.查看文件系统的属性 5.挂载 6.buffer和cache 一、文件系统 1.分区 1-4个主分区 第五个序号开始&#xff0c;是逻辑分区 2.文件系统分类 vfs文件系统 ------------- virtualenv file System&#xff0…

智慧社区燃气管网监测系统

燃气易燃易爆&#xff0c;一旦操作不当或疏忽大意&#xff0c;极易引发燃气安全事故&#xff0c;造成严重后果&#xff0c;2023年10月24日&#xff0c;在吉林某小区&#xff0c;发生了燃气使用不当产生的爆炸导致了1人死亡&#xff0c;1人重伤&#xff0c;15人轻伤&#xff0c;…

【嵌入式开源库】timeslice的使用,完全解耦的时间片轮询框架构

完全解耦的时间片轮询框架构 简介项目代码timeslice.htimeslice.clist.hlist.c 创建工程移植代码实验函数说明timeslice_task_inittimeslice_task_addtimeslice_tak_deltimeslice_get_task_num 结尾 简介 timeslice是一个时间片轮询框架&#xff0c;他是一个完全解耦的时间片轮…

电脑视频怎么转音频mp3

如果你在电脑上观看视频时喜欢上某个片段的背景音乐&#xff0c;且想将喜欢的背景音乐制作为手机铃声。我是建议你将此视频转换为 MP3 格式&#xff0c;因为 MP3 几乎与所有设备相兼容&#xff0c;让你可以在不同设备上不受限制地去聆听它。那该如何转换呢&#xff1f;无需担心…

LinkedList概念+MyLinkedList的实现

文章目录 LinkedList笔记一、 LinkedList1.概念2.LinkedList的构造方法3.LinkedList的遍历 二、MyLinkedList的实现1.定义内部类2.打印链表、求链表长度、判断是否包含关键字3. 头插法和尾插法4.在任意位置插入5.删除结点6.清空链表 LinkedList笔记 一、 LinkedList 1.概念 L…

将两个有序顺序表合并为一个新的有序顺序表,并由函数返回结果顺序表

将两个有序顺序表合并为一个新的有序顺序表&#xff0c;并由函数返回结果顺序表 算法思路&#xff1a; 这个其实就是一个归并排序&#xff0c;我们这里两顺序表为升序&#xff0c;要合并成一个升序表 用i和j分别标记顺序表A和顺序表B的元素&#xff0c;然后新表是C 每次从A和…

HarmonyOS 自定义抽奖转盘开发(ArkTS)

介绍 本篇 Codelab 是基于画布组件、显式动画&#xff0c;实现的一个自定义抽奖圆形转盘。包含如下功能&#xff1a; 1. 通过画布组件 Canvas&#xff0c;画出抽奖圆形转盘。 2. 通过显式动画启动抽奖功能。 3. 通过自定义弹窗弹出抽中的奖品。 相关概念 ● Stack组件…

web自动化测试框架介绍

一、目的 web自动化测试作为软件自动化测试领域中绕不过去的一个“香饽饽”&#xff0c;通常都会作为广大测试从业者的首选学习对象&#xff0c;相较于C/S架构的自动化来说&#xff0c;B/S有着其无法忽视的诸多优势&#xff0c;从行业发展趋、研发模式特点、测试工具支持&…

PMP考试是如何提高项目管理能力的?

通过获得PMP认证&#xff0c;项目管理人员可以提高其项目管理能力&#xff0c;并在行业中取得更高的职业发展。PMP如何提高项目管理能力&#xff0c;具体体现在以下几个方面&#xff1a; 1. 标准化方法&#xff1a; PMP认证基于《项目管理知识体系指南》(PMBOK)&#xff0c;该…

如何设计实时聊天系统的架构

1. 系统的要求和目标 1.1 功能要求 对话&#xff1a;系统应支持用户之间的一对一和群组对话。确认消息&#xff1a;系统应支持消息传递确认&#xff0c;如已发送、已送达、已读。共享&#xff1a;系统应支持媒体文件的共享&#xff0c;例如图像、视频和音频。聊天存储&#x…

IT行业哪个方向比较好就业?

IT行业哪个方向比较好就业? IT行业哪个方向比较好就业?引言IT技术发展背景及历程IT行业的就业方向有哪些&#xff1f;1. 软件开发2. 网络安全3. 数据分析4. 人工智能和机器学习5. 云计算6. 物联网&#xff08;IoT&#xff09;7. 软件测试与质量保障8. 区块链 分享在IT行业的就…