Concurrency 在单个Redis连接上交错观看Multi/exec。预期的还是奇怪的行为?
考虑一个正面应用程序,其中每个请求共享相同的Redis连接,我认为这是推荐的方式(?) 在这种情况下,我相信我看到了一些奇怪的Concurrency 在单个Redis连接上交错观看Multi/exec。预期的还是奇怪的行为?,concurrency,redis,Concurrency,Redis,考虑一个正面应用程序,其中每个请求共享相同的Redis连接,我认为这是推荐的方式(?) 在这种情况下,我相信我看到了一些奇怪的观察multi/exec行为。具体地说,我预计两个事务中的一个会因为乐观锁定失败而失败(即,watchguard),但这两个事务似乎都没有发脾气,但会导致错误的最终值 为了说明,请参见下面的人为场景。它在节点中,但我相信这是一般的事情。这将并行运行两个进程,这两个进程都会更新计数器。(它基本上实现了表的规范示例,如中所示 预期结果是,第一个进程的结果是增量为1,而第二个进
观察multi/exec
行为。具体地说,我预计两个事务中的一个会因为乐观锁定失败而失败(即,watch
guard),但这两个事务似乎都没有发脾气,但会导致错误的最终值
为了说明,请参见下面的人为场景。它在节点中,但我相信这是一般的事情。这将并行运行两个进程,这两个进程都会更新计数器。(它基本上实现了表的规范示例,如中所示
预期结果是,第一个进程的结果是增量为1,而第二个进程未能更新并返回null
。相反,结果是两个进程都用1更新计数器。但是,其中一个进程基于过时的计数器,因此最后计数器的增量为1,而不是2
//NOTE: db is a promisified version of node-redis, but that really doesn't matter
var db = Source.app.repos.redis._raw;
Promise.all(_.reduce([1, 2], function(arr, val) {
db.watch("incr");
var p = Promise.resolve()
.then(function() {
return db.get("incr");
})
.then(function(val) { //say 'val' returns '4' for both processes.
console.log(val);
val++;
db.multi();
db.set("incr", val);
return db.exec();
})
.then(function(resultShouldBeNullAtLeastOnce) {
console.log(resultShouldBeNullAtLeastOnce);
return; //explict end
});
arr.push(p);
return arr;
}, [])).then(function() {
console.log("done all");
next(undefined);
})
当跟踪Redis的监视器命令时,可以看到结果交错:
1414491001.635833 [0 127.0.0.1:60979] "watch" "incr"
1414491001.635936 [0 127.0.0.1:60979] "watch" "incr"
1414491001.636225 [0 127.0.0.1:60979] "get" "incr"
1414491001.636242 [0 127.0.0.1:60979] "get" "incr"
1414491001.636533 [0 127.0.0.1:60979] "multi"
1414491001.636723 [0 127.0.0.1:60979] "set" "incr" "5"
1414491001.636737 [0 127.0.0.1:60979] "exec"
1414491001.639660 [0 127.0.0.1:60979] "multi"
1414491001.639691 [0 127.0.0.1:60979] "set" "incr" "5"
1414491001.639704 [0 127.0.0.1:60979] "exec"
这是预期的行为吗?使用多个redis连接是否可以避免此问题?回答我自己的问题: 这是预期的行为。第一个
exec
取消对所有属性的检查。因此,第二个multi/exec
在没有监视保护的情况下通过
它在地下室,但它相当隐蔽
解决方案:使用多个连接,尽管有一些答案明确警告不要这样做,因为它(引号)“不需要”。在这种情况下,它是需要的。什么是“错误的最终值”您得到的是?5或10?
incr
的值是4
,在两个进程都增加后,该值是5
。该值是预期值,但第二个事务应该失败,因为incr
的值已从4
更改为5
,因此监视-guar第二个事务上的d应该失败。这不会happen@itamarHaber,可能就是这样。使用多个Redis连接,会正确导致watch guard失败。的dublicate