目前在 nuget 中,我不这么认为。因为 BookSleeve通常被用作多路复用器,这使得“watch”无法使用。我可以添加它,但您必须在操作期间将使用限制为单个调用者(每个 BookSleeve 连接)。
这个has now changed;如果我们想手动实现INCR(根据您的示例),我们可以使用:
// note this could be null if the old key didn't exist
var oldVal = await connection.Strings.GetInt64(db, key);
var newVal = (oldVal ?? 0) + 1;
using (var tran = connection.CreateTransaction())
{
// check hasn't changed (this handles the WATCH, a checked GET,
// and an UNWATCH if necessary); note tat conditions are not sent
// until the Execute is called
tran.AddCondition(Condition.KeyEquals(db, key, oldVal));
// apply changes to perform assuming the conditions succeed
tran.Strings.Set(db, key, newVal); // the SET
// note that Execute includes the MULTI/EXEC, assuming the conditions pass
if (!await tran.Execute()) return null; // aborted; either a pre-condition
// failed, or a WATCH-key was changed
return newVal; // successfully incremented
}
显然,您可能希望在重复的(在合理的范围内)循环中执行该操作,以便如果由于 WATCH 而中止它,您可以从头开始重做。
这与您的示例略有不同,实际上是这样(假设初始 GET 和第二个 GET 之间的值没有改变):
val = GET mykey
newval = (val ?? 0) + 1
WATCH mykey
chk = GET mykey // and verifies chk == val as part of the Execute
MULTI
SET mykey $newval
EXEC
请注意,如果值在 WATCH 和 EXEC 之间更改,EXEC 仍然可以报告取消;或(如果它已在两个GETs 之间发生变化):
val = GET mykey
newval = (val ?? 0) + 1
WATCH mykey
chk = GET mykey // and verifies chk == val as part of the Execute
UNWATCH
不同之处在于多了一个GET,但这是它与多路复用器一起工作的唯一方式——即,Execute 被优化为可靠快速,因此它不会影响其他调用者。