lua脚本笔记、redis使用lua解锁

文章目录

lua是一门独立的语言。
用lua来解锁redis是非常流行的一种方式。

下载、安装、环境配置

1、官网首页 | 点 download,不要选tag.gz版本,要选预编译版本Pre-compiled后面的LuaBinaries。如图:

2、再点左侧的download,选对应版本下载,例如windows选这个:

3、解压后里面有lua55.exe等程序、将这个文件夹添加到环境变量

4、新打开cmd窗口,输入lua55,出现版本号表示成功。

5、复制lua55.exe,命名为lua.exe,这样用起来方便。

lua解锁redis实践

最佳实践或者通用场景如下:

1、加锁用setIfAbsent

2、解锁用lua

如果使用luaj,那么linux环境连lua都不需要支持,java包里面直接自带了,方便的很。

示例1

代码:

java 复制代码
String lockKey = "myLock";
String requestId = UUID.randomUUID().toString();

try {
    // 1. 加锁 (带过期时间)
    Boolean locked = redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, 10, TimeUnit.SECONDS);
    
    if (Boolean.TRUE.equals(locked)) {
        // 2. 执行业务
        doSomething();
    } else {
        // 获取锁失败处理
    }
} finally {
    // 3. 必须主动解锁!
    // 注意:这里最好用 Lua 脚本判断 requestId 再删除,防止误删
    if (isLocked) {
        unlockWithLuaScript(lockKey, requestId); 
    }
}
示例2

代码:

java 复制代码
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;

import java.util.Collections;
import java.util.UUID;

public class RedisLockUtil {

    private final RedisTemplate<String, Object> redisTemplate;

    public RedisLockUtil(RedisTemplate<String, Object> redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    /**
     * 1. 定义 Lua 脚本
     * 逻辑:如果 key 存在 且 value 等于 myId,则删除 key,返回 1;否则返回 0
     */
    private static final String UNLOCK_LUA_SCRIPT =
            "if redis.call('get', KEYS[1]) == ARGV[1] then " +
            "   return redis.call('del', KEYS[1]) " +
            "else " +
            "   return 0 " +
            "end";

    /**
     * 加锁方法 (为了完整性)
     */
    public boolean lock(String lockKey, String requestId, long expireTime) {
        return Boolean.TRUE.equals(redisTemplate.opsForValue()
                .setIfAbsent(lockKey, requestId, expireTime, java.util.concurrent.TimeUnit.SECONDS));
    }

    /**
     * 2. 解锁方法 (核心部分)
     */
    public void unlock(String lockKey, String requestId) {
        // 封装脚本对象,指定返回类型为 Long
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setScriptText(UNLOCK_LUA_SCRIPT);
        script.setResultType(Long.class);

        try {
            // 执行脚本
            // 参数1: 脚本对象
            // 参数2: KEYS 列表 (这里只有一个锁的 key)
            // 参数3: ARGV 列表 (这里是要比对的 requestId)
            Long result = redisTemplate.execute(
                    script, 
                    Collections.singletonList(lockKey), 
                    requestId
            );

            if (result != null && result == 1) {
                System.out.println("解锁成功: " + lockKey);
            } else {
                System.out.println("解锁失败: 锁不存在或不是当前线程持有");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // --- 测试主函数 ---
    public static void main(String[] args) throws InterruptedException {
        // 假设你已经配置好了 RedisTemplate (这里仅作伪代码示意)
        // RedisTemplate<String, Object> template = ... 
        
        // RedisLockUtil lockUtil = new RedisLockUtil(template);
        
        String lockKey = "order_lock_001";
        String myId = UUID.randomUUID().toString(); // 唯一标识

        // 模拟加锁
        // boolean isLock = lockUtil.lock(lockKey, myId, 10);
        
        try {
            // if (isLock) {
                System.out.println("业务执行中...");
                Thread.sleep(1000);
            // }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 模拟解锁
            // lockUtil.unlock(lockKey, myId);
        }
    }
}

pycharm运行lua脚本

vscode就很不错,pycharm也可以。

先安装插件emmylua。

在.lua文件上,点运行配置:

1、新建lua application

2、配置lua.exe的位置

3、选要执行的.lua文件,点运行配置

其他

文档

lua官网(速度快):
https://www.lua.org/

相关推荐
SeSs IZED15 分钟前
Redis开启远程连接
数据库·redis·缓存
东京老树根26 分钟前
SAP学习笔记 - BTP SAP Build05 - SAP BTP BPA简介,Email Destination Settings(TODO)
笔记·学习
talen_hx2961 小时前
《零基础入门Spark》学习笔记 Day 17
大数据·笔记·学习·spark
北山有鸟1 小时前
Linux第一宏:container_of
笔记·嵌入式硬件·学习
后端漫漫2 小时前
Redis 配置文件与服务功能
java·redis
做cv的小昊2 小时前
【TJU】研究生应用统计学课程笔记(2)——第一章 数理统计的基本知识(1.3 统计中常用的分布族)
笔记·线性代数·数学建模·矩阵·概率论·学习方法·抽象代数
ouliten2 小时前
cuda编程笔记(38)--CUDA 异步回调
笔记·cuda
Better Bench2 小时前
《八十天环游地球》阅读笔记
笔记·读书笔记·八十天环游地球
sheeta19982 小时前
LeetCode 每日一题笔记 日期:2026.04.21 题目:1722. 执行交换操作后的最小汉明距离
笔记·算法·leetcode
12亡灵归来343 小时前
Postman高级用法:自动化测试与Mock
测试工具·lua·postman