script/decr.lua
-- 如果不存在, 则设置值和过期时间 返回
-- 如果已经存在, 直接自减, 过期时间保持不变
local value = redis.call('EXISTS', KEYS[1])
if value == 0 then
redis.call('set', KEYS[1], ARGV[1], 'EX', ARGV[2])
return ARGV[1]
else
return redis.call('decr', KEYS[1])
end
java 代码如下
decrLuaScript = new DefaultRedisScript<>();
decrLuaScript.setResultType(Long.class);
decrLuaScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("script/decr.lua")));
Long result = atomicRedisTemplate.execute(decrLuaScript, ImmutableList.of(key), initValue, seconds);
assert Objects.nonNull(result);
测试发现如果是没有初始值, 结果返回的 null, 如果已有初始值可以正常返回 decr 后的结果
更奇怪的是.. 在 redis-cli 里面手动执行是可以返回初始值的
127.0.0.1:6379> eval "local value = redis.call('EXISTS', KEYS[1]) if value == 0 then redis.call('set', KEYS[1], ARGV[1], 'EX', ARGV[2]) return ARGV[1] else return redis.call('decr', KEYS[1]) end" 1 xxx 100 300
"100"
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.