使用Lua原因
轻量
脚本执行原子化,这对于多线程或者多进程的环境中很重要。
使用常用的EVAL 命令:
EVAL script numkeys key [key …] arg [rg …]
加锁
localhost:0>eval "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end" 1 user.lock lockid1 50
"1"
localhost:0>eval "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end" 1 user.lock lockid1 50
"0"
localhost:0>ttl user.lock
"33"
localhost:0>ttl user.lock
"31"
localhost:0>
注意value的设置,需要设置加锁放的id,防止误删除别人加的锁
解锁
localhost:0>eval "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end" 1 user.lock lockid1 50
"1"
localhost:0>eval "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end" 1 user.lock lockid1 50
"0"
localhost:0>eval "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 ; end" 1 user.lock lockid1
"1"
localhost:0>eval "if redis.call('EXISTS', KEYS[1]) == 0 then redis.call('set', KEYS[1], ARGV[1]) redis.call('expire', KEYS[1], ARGV[2]) return 1 else return 0 end" 1 user.lock lockid1 50
"1"
localhost:0>
注意解锁时,需要判定是value是自己加的锁才解锁,防止解除别人的锁