我在nodejs
中有以下代码:
const decrease = async (userId, points) => {
const user = await redisClient.hgetall(userId);
if(user.points - points >= 0) {
await redisClient.hset(userId, userId, user.points - points);
}
}
由于async/await
没有阻止执行,如果对同一userId有多个请求,则代码不会以原子方式运行。这意味着即使用户帐户上没有足够的点,用户点也可能会多次减少。如何使方法以原子方式运行?
我检查了redis multi
命令,它适用于多个redis语句。但在我的情况下,我需要计算不属于redis命令的用户点。那么如何使它们作为原子函数运行。
我还阅读了INCR模式:https://redis.io/commands/incr 但它似乎没有解决我的问题。那里列出的模式需要使用expire,我没有这样的要求给出特定的超时值。
答案 0 :(得分:1)
通过调用EVAL
来使用(Redis)服务器端Lua脚本的强大功能。它应该看起来像这样:
const lua = `
local p = redis.call('HGET',KEYS[1],'points')
local d = p - ARGV[1]
if d >= 0 then
redis.call('HSET', KEYS[1], 'points', d)
end`
const decrease = async (userId, points) => {
await redisClient.eval(lua, 1, userId, points);
}