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/

相关推荐
cfm_29146 小时前
Redis五大基本数据结构底层了解
数据结构·数据库·redis
真实的菜7 小时前
Redis 从入门到精通(十二):典型业务场景实战 —— 排行榜、限流器、秒杀系统、Session 共享
数据库·redis·python
qeen878 小时前
【C++】类与对象之类的默认成员函数(二)
android·c语言·开发语言·c++·笔记·学习
m0_736034858 小时前
存储基础和虚拟化
笔记
AOwhisky10 小时前
MySQL 学习笔记(第六期):MySQL 备份与恢复
运维·数据库·笔记·学习·mysql·云计算
华山沦贱11 小时前
open62541 V1.5.4版对C++ Builder支持的bug
笔记
x***r15111 小时前
Redis Desktop Manager 0.8.8 安装教程(Windows redis-desktop-manager-0.8.8.384详细步骤)
数据库·windows·redis
稷下元歌12 小时前
七天学会plc 加机器视觉完整笔记:S7-1200 数据类型、存储区与寻址方式(I/Q/M/DB 详解)。
网络·数据库·笔记
无涯大者12 小时前
Redis 实现页面缓存、购物车、登录 token示例、点赞 / 阅读计数,排行榜 示例
redis·缓存
逸模12 小时前
AI+BIM 重构连锁公装新范式 逸模打造数字化营建核心底座
大数据·人工智能·笔记·其他·信息可视化·重构