Ensuring two redis commands are atomic if the second comman

确保两个redis是原子的第二命令

问题 (Question)

Using the node_redis client, how can I make two commands execute such that they will be performed atomically when the second command relies on the result of the first.

Here is an example of what I am thinking.

client.multi([
    ["hget", orgId, topicId]
]).exec(function (err, sessions) {
    sessions = JSON.parse(sessions);
    if (sessions === undefined) {
        sessions = [sessionId];
    }
    else {
        sessions.push(sessionId)
    }
    client.hset(orgId, topicId, JSON.stringify(sessions)]);
});

Can someone confirm there would not be a race condition to write back the new value if this ran simultaneously in two places.

使用node_redis客户端,我如何能让两个命令执行,他们将自动执行命令时,二靠前的结果。

下面是一个例子,我在想什么。

client.multi([
    ["hget", orgId, topicId]
]).exec(function (err, sessions) {
    sessions = JSON.parse(sessions);
    if (sessions === undefined) {
        sessions = [sessionId];
    }
    else {
        sessions.push(sessionId)
    }
    client.hset(orgId, topicId, JSON.stringify(sessions)]);
});

有人能确认不会有比赛的状况写回新的价值,如果同时在两个地方跑了。

最佳答案 (Best Answer)

The right answer is to "watch" the value. It is also important to make sure each query has its own connection and handles the possibility of a concurrency error.

var atomicReadWriteOperationRecursive = function (hashKey, valueKey, count) {
    var client = redis.createClient();
    client.watch(hashKey, valueKey);
    client.hget(hashKey, valueKey, function (err, response) {
            client.multi()
                .hset(orgId, topicId, newValue);
                .exec(function (err) {
                    client.close();
                    if (err && count < 3) {
                        atomicReadWriteOperationRecursive(hashKey, valueKey, count++);  
                    }
                });
        });
}

See here https://github.com/mranney/node_redis/issues/545.

正确的答案是“看”的价值。同样重要的是要确保每个查询都有它自己的连接和处理并发错误的可能性。

var atomicReadWriteOperationRecursive = function (hashKey, valueKey, count) {
    var client = redis.createClient();
    client.watch(hashKey, valueKey);
    client.hget(hashKey, valueKey, function (err, response) {
            client.multi()
                .hset(orgId, topicId, newValue);
                .exec(function (err) {
                    client.close();
                    if (err && count < 3) {
                        atomicReadWriteOperationRecursive(hashKey, valueKey, count++);  
                    }
                });
        });
}

在这里看到的https://github.com/mranney/node_redis/issues/545

本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:http://stackoverflow.com/questions/21507886