Redis 不直接支持这一点,但在许多情况下,这通常是需要的。更广义的“原子”模式是:
Check multiple conditions
If all satisfied, run multiple commands
这可以通过简单的 lua 脚本来实现
-- Validate conditions and exec commands if ok
local params = cjson.decode(ARGV[1])
-- Check conditions
for __, check in pairs(params["if"]) do
if #check == 2 then
if check[1] ~= redis.call(unpack(check[2])) then return 0 end
elseif check[2] == "==" then
if check[1] ~= redis.call(unpack(check[3])) then return 0 end
elseif check[2] == "!=" then
if check[1] == redis.call(unpack(check[3])) then return 0 end
elseif check[2] == ">" then
if check[1] <= redis.call(unpack(check[3])) then return 0 end
elseif check[2] == "<" then
if check[1] >= redis.call(unpack(check[3])) then return 0 end
else
error('invalid operator "'..tostring(check[2])..'" (expected "==", "!=", ">" or "<")')
end
end
-- Eval redis commands
for __, exec in pairs(params["exec"]) do
redis.call(unpack(exec))
end
return 1
然后可以简单地传递交易细节JSON.stringify(object)
:
{
// Conditions. All must be satisfied
if: [
[ 'initialized', '==', [ 'sget', 'custom-state' ] ]
],
// Commands to execute if all conditions are satisfied
exec: [
[ 'set', 'custom-state', 'finished' ],
[ 'incr', 'custom-counter' ]
]
}
在许多情况下,此类“条件事务”消除了对自定义脚本的需求。
有关更多示例/测试/src,请参阅https://github.com/nodeca/redis-if。