文章目录
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/