脚本案例
/**
* KEYS[1] 单个用户中奖总数
* KEYS[2] 奖品项 每日中奖数
* KEYS[3] 奖品项 总数量
* <p>
* ARGV[1] 单个用户中奖总数 最大值
* ARGV[2] 奖品项 每日中奖数 每日中奖数
* ARGV[3] 奖品项 最大值
* <p>
* ARGV[4] 剩余 TTL时间
*/
private final static DefaultRedisScript<List> JudgeHitTimesScript = new DefaultRedisScript<>(
"local result={}" +
"local userMaxTimes = tonumber(ARGV[1]);" +
"local packageOrderDayTimes = tonumber(ARGV[2]);" +
"local packageOrderMaxTimes = tonumber(ARGV[3]);" +
"local userAmount = redis.call('INCR',KEYS[1]); " +
"if userMaxTimes >0 and userAmount > userMaxTimes then redis.call('DECR', KEYS[1]) result[1] = -102; return result end;" +
"local packageOrderDayAmount = redis.call('INCR',KEYS[2]); " +
"if packageOrderDayTimes > 0 and packageOrderDayAmount > packageOrderDayTimes then redis.call('DECR', KEYS[1]) ; redis.call('DECR', KEYS[2]); result[1] = -103; return result end;" +
"local packageOrderAmount = redis.call('INCR',KEYS[3]); " +
"if packageOrderMaxTimes > 0 and packageOrderAmount > packageOrderMaxTimes then redis.call('DECR', KEYS[1]) ; redis.call('DECR', KEYS[2]); redis.call('DECR', KEYS[3]); " +
"result[1] = -104; result[2] = packageOrderMaxTimes; result[3] = packageOrderAmount; return result end;" +
"local exists_flag = redis.call('ttl', KEYS[2]); " +
"if exists_flag == -1 then redis.call('expire', KEYS[2], ARGV[3]) end; " +
"result[1] = 1; result[2] = userMaxTimes; result[3] = packageOrderDayTimes; result[3] = packageOrderMaxTimes; return result",
List.class
);
接口触发
List result = stringRedisTemplate.execute(JudgeHitTimesScript, keys, String.valueOf(userMaxHitTimes), String.valueOf(itemPerDayHitTimes), String.valueOf(itemCountTimes), String.valueOf(ttlSeconds));
该文章介绍了一个使用Redis和Lua脚本实现的中奖系统,通过Lua脚本控制单个用户中奖次数和奖品每日中奖数不超过预设的最大值。当超过限制时,脚本会进行回滚并返回错误码。同时,脚本还处理了奖品项总数量的限制及TTL时间管理。
9670

被折叠的 条评论
为什么被折叠?



