From 33ea0a5a7edfa26c49c31da7345c2b6995d08c2b Mon Sep 17 00:00:00 2001 From: Wonder Date: Tue, 21 Oct 2025 22:46:12 +0800 Subject: [PATCH] =?UTF-8?q?=20=F0=9F=94=84Update:=20=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E7=82=B9=E8=B5=9E=E4=B8=9A=E5=8A=A1=E7=9B=B8=E5=85=B3=20Lua=20?= =?UTF-8?q?=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../constant/RedisLuaScriptConstant.java | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 src/main/java/cn/hezhaohui/thumb/constant/RedisLuaScriptConstant.java diff --git a/src/main/java/cn/hezhaohui/thumb/constant/RedisLuaScriptConstant.java b/src/main/java/cn/hezhaohui/thumb/constant/RedisLuaScriptConstant.java new file mode 100644 index 0000000..e39164c --- /dev/null +++ b/src/main/java/cn/hezhaohui/thumb/constant/RedisLuaScriptConstant.java @@ -0,0 +1,74 @@ +package cn.hezhaohui.thumb.constant; + +import org.springframework.data.redis.core.script.DefaultRedisScript; +import org.springframework.data.redis.core.script.RedisScript; + +public class RedisLuaScriptConstant { + + /** + * 点赞 Lua 脚本 + * KEYS[1] -- 临时计数键 + * KEYS[2] -- 用户点赞状态键 + * ARGV[1] -- 用户 ID + * ARGV[2] -- 博客 ID + * 返回: + * -1: 已点赞 + * 1: 操作成功 + */ + public static final RedisScript THUMB_SCRIPT = new DefaultRedisScript<>(""" + local tempThumbKey = KEYS[1] -- 临时计数键(如 thumb:temp:{timeSlice}) + local userThumbKey = KEYS[2] -- 用户点赞状态键(如 thumb:{userId}) + local userId = ARGV[1] -- 用户 ID + local blogId = ARGV[2] -- 博客 ID + + -- 1. 检查是否已点赞(避免重复操作) + if redis.call('HEXISTS', userThumbKey, blogId) == 1 then + return -1 -- 已点赞,返回 -1 表示失败 + end + + -- 2. 获取旧值(不存在则默认为 0) + local hashKey = userId .. ':' .. blogId + local oldNumber = tonumber(redis.call('HGET', tempThumbKey, hashKey) or 0) + + -- 3. 计算新值 + local newNumber = oldNumber + 1 + + -- 4. 原子性更新:写入临时计数 + 标记用户已点赞 + redis.call('HSET', tempThumbKey, hashKey, newNumber) + redis.call('HSET', userThumbKey, blogId, 1) + + return 1 -- 返回 1 表示成功 + """, Long.class); + + /** + * 取消点赞 Lua 脚本 + * 参数同上 + * 返回: + * -1: 未点赞 + * 1: 操作成功 + */ + public static final RedisScript UNTHUMB_SCRIPT = new DefaultRedisScript<>(""" + local tempThumbKey = KEYS[1] -- 临时计数键(如 thumb:temp:{timeSlice}) + local userThumbKey = KEYS[2] -- 用户点赞状态键(如 thumb:{userId}) + local userId = ARGV[1] -- 用户 ID + local blogId = ARGV[2] -- 博客 ID + + -- 1. 检查用户是否已点赞(若未点赞,直接返回失败) + if redis.call('HEXISTS', userThumbKey, blogId) ~= 1 then + return -1 -- 未点赞,返回 -1 表示失败 + end + + -- 2. 获取当前临时计数(若不存在则默认为 0) + local hashKey = userId .. ':' .. blogId + local oldNumber = tonumber(redis.call('HGET', tempThumbKey, hashKey) or 0) + + -- 3. 计算新值并更新 + local newNumber = oldNumber - 1 + + -- 4. 原子性操作:更新临时计数 + 删除用户点赞标记 + redis.call('HSET', tempThumbKey, hashKey, newNumber) + redis.call('HDEL', userThumbKey, blogId) + + return 1 -- 返回 1 表示成功 + """, Long.class); +}