redis分布式锁为什么采用Lua脚本实现。而不是事务

Redis 分布式锁使用 Lua 脚本而非事务,核心原因是 Lua 脚本能保证分布式锁操作的 "原子性" 和 "灵活性",而 Redis 事务在某些场景下无法满足分布式锁的核心需求。

一、Redis事务的局限性

redis分布式锁的核心是先判断自己是否持有锁,然后在进行释放。

用 Redis 事务实现时,需要分两步:

java 复制代码
MULTI
GET lock:key  # 1. 判断锁是否归属自己
DEL lock:key  # 2. 释放锁(仅当归属自己时)
EXEC

但 Redis 事务是 "批量执行,无中间判断" 的 ------GETDEL 会被强制一起执行,无法根据 GET 的结果决定是否执行 DEL。即使锁已被其他客户端抢占,DEL 仍会执行,导致 "误释放他人锁" 的严重问题。

二、lua脚本的优势

Lua脚本能够保障redis服务端原子性的执行一系列的命令,且不会被其它客户端打断,确保条件判断和后续操作的原子性

如释放锁的Lua脚本:

java 复制代码
-- 释放锁:仅当锁的value是自己的标识时才删除
if redis.call("GET", KEYS[1]) == ARGV[1] then
    return redis.call("DEL", KEYS[1])  -- 释放锁
else
    return 0  -- 不释放他人的锁
end

这段脚本会原子性地完成 "判断锁归属" 和 "释放锁" 两个操作,避免了事务中 "判断和执行分离" 的问题。

同时Lua可以提高分布式锁的性能,

分布式锁的操作(如 "判断 + 释放")若用多条命令分步执行,需要多次网络往返(客户端→Redis→客户端)。

用 Lua 脚本可以将多步操作合并为一次网络请求,减少网络延迟,尤其在分布式环境中能显著提升性能

补充:为什么Lua脚本是单线程的?

Redis 是单线程处理命令的,

整个脚本会被当作一个不可分割的整体,在执行过程中不会被其他客户端的命令打断,直到脚本完全执行完毕,

同时Redis 明确禁止在 Lua 脚本中执行会阻塞主线程的操作 (如BRPOP等阻塞命令、长时间循环)。这确保了 Lua 脚本的执行时间是可控的,不会因为脚本执行过久导致 Redis 无法处理其他请求。

相关推荐
用户3074596982072 天前
Redis 延时队列详解
redis
烤代码的吐司君3 天前
Redis 数据结构 ZSet, BIT, HyperLogLog,Geo 空间数据
redis·后端
leeyi5 天前
Checkpoint 机制:Agent 怎么在断电后接着跑
redis·aigc·agent
云技纵横6 天前
一个 @Async 让循环依赖暴雷:Spring 代理的暗坑
redis
犯困蛋挞yy7 天前
用Claude快速解决Redis代码报错反复无解的问题
redis
用户31693538118313 天前
Java连接Redis
redis
小小工匠15 天前
Redis - 事务机制:能实现 ACID 属性吗
数据结构·redis·性能优化·并发·持久化
xingpanvip15 天前
星盘接口开发文档:本命盘接口指南
android·开发语言·css·php·lua
骇客之技术15 天前
AutoLua:在安卓上写 Lua 脚本
android·junit·lua
taocarts_bidfans15 天前
反向海淘跨境缓存架构优化:taocarts Redis分层缓存实战技术
redis·缓存·架构·反向海淘·taocarts