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/

相关推荐
江屿风20 分钟前
【科普】【差集&交集概念落地云相册】流食般投喂
开发语言·c++·笔记·算法·云相册
一米阳光866110 小时前
软考(中级)软件设计师核心笔记(6)系统开发基础——需求分析、系统设计
笔记·职场发展·需求分析·软考·软件设计师·中级职称
雨田言炎13 小时前
四、关于Qt项目需要知道的
开发语言·笔记·qt
hanlin0314 小时前
动态规划专练:力扣第121、122题
笔记·算法·leetcode
摇滚侠15 小时前
SpringBoot 官网 阅读笔记 启用生产就绪功能 端点
spring boot·笔记·后端
AI云海16 小时前
完整机器学习工业项目流水线笔记
人工智能·笔记·机器学习
2601_9657996816 小时前
2026 在线笔试平台深度测评与选型指南:从功能、稳定性、AI能力、防作弊全面分析
人工智能·笔记·功能测试
xqqxqxxq16 小时前
SQL 连接查询技术笔记
数据库·笔记·sql
消失的旧时光-194317 小时前
第六篇:Redis Hash——一个用户对象应该保存成 JSON,还是保存成 Hash?
redis·json·哈希算法
尤乐娃子17 小时前
进入大厂(厂子大)实习Day11
前端·笔记·实习