我正在使用redis-py通过Python与redis进行交互。我处于这样一种情况:在原子更新哈希键之前,需要检索该键上的值。查看文档时,似乎可以使用管道和WATCH命令来确定键何时更改。是否有办法在哈希内部监视一个键?还是只适用于单个键?
K
:
lock:K
lock:K
""/**
* Concurrently updates Redis string and hash value under the specified key.
*
* @param redisCli Redis client.
* @param hashName Hash name.
* @param objId Object ID.
* @param transFun Cache object transformation function (i.e. a modification that we need to apply).
* @param cbFun Callback function, to which a modified object is passed in case of success.
*/
exports.redisUpdateHashConcurrently = function(redisCli, hashName, objId, transFun, cbFun) {
var lockKey = hashName + ':' + objId + ':lock';
redisCli.watch(lockKey); // Step 1.
redisCli.hget(hashName, objId, function(err, obj) { // Step 2.
if (err) {
redisCli.unwatch();
cbFun && cbFun(undefined, err);
return;
}
if (obj) {
var modObj = transFun(JSON.parse(obj));
var value = JSON.stringify(modObj);
redisCli.multi() // Step 3.
.set(lockKey, '') // Step 4.
.expire(lockKey, 3)
.hset(hashName, objId, value) // Step 5.
.exec(function(err, replies) { // Step 6.
if (!replies) { // Object was modified by someone else, retry.
exports.redisUpdateHashConcurrently(redisCli, hashName, objId, transFun, cbFun);
}
else { // We have succeeded.
cbFun && cbFun(modObj, undefined);
}
});
}
else {
redisCli.unwatch();
}
});
};
lock:K
,因此如果这种情况同时发生,则lock:K
的值不会被更新。在这种情况下,EXEC
仍然会失败吗?我的意思是在https://redis.io/topics/transactions中写道:“我们要求Redis仅在未修改任何WATCHed键的情况下执行事务”。 - mashEXEC
仍然失败。 - Joe Daley使用MULTI如何?这样你就不需要担心在哈希表中观察键(WATCH似乎不支持,正如你所建议的那样)。