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 无法处理其他请求。

相关推荐
梦中的天之酒壶3 小时前
Redis Stack扩展功能
数据库·redis·bootstrap
在未来等你3 小时前
Elasticsearch面试精讲 Day 12:数据建模与字段类型选择
大数据·分布式·elasticsearch·搜索引擎·面试
a587694 小时前
消息队列(MQ)初级入门:详解RabbitMQ与Kafka
java·分布式·microsoft·面试·kafka·rabbitmq
Hello.Reader5 小时前
Kafka在多环境中安全管理敏感
分布式·安全·kafka
MAGICIAN...5 小时前
【Redis五种数据类型】
数据库·redis·缓存
吐泡泡_5 小时前
Redis(主从复制)
redis
凯子坚持 c7 小时前
Redis核心通用命令深度解析:结合C++ redis-plus-plus 实战指南
c++·redis·log4j