[英]How to do basic WATCH with StackExchange.Redis
我想用StackExchange.Redis做一個基本的手表。 如果在事務期間更改了密鑰,則會失敗。
StackExchange.Redis很好地抽象了一個“Condition”api,它支持“Equals”和“Exists”的概念。
這真的很好,但我想做一些像“未改變”的事情。 我可能會遺漏一些東西,但目前對於如何做到這一點並不明顯。
有可能做這樣的事情:
var transaction = redis.CreateTransaction();
transaction.AddCondition(Condition.StringUnchanged("key")); //the API here could maybe be simplified
var val = transaction.StringGet("key"); //notably, this is not async because you would have to get the result immediately - it would only work on watched keys
transaction.StringSetAsync("key", val + 1);
transaction.Execute();
或者甚至是一個可能更好的版本(它會做同樣的事情):
var transaction = redis.CreateTransaction();
var val = transaction.Watch("key"); //this would return the value!
transaction.StringSetAsync("key", val + 1);
transaction.Execute();
目前,我理解這樣做的唯一方法是做一些事情:
var val = redis.StringGet("key");
var transaction = redis.CreateTransaction();
transaction.AddCondition(Condition.StringEqual("key", val));
transaction.StringSetAsync("key", val + 1);
transaction.Execute();
從嘗試閱讀SE.Redis代碼,我理解翻譯成類似的東西(不確定這是多么准確):
val = GET key
WATCH key
MULTI
val = val + 1
SET key $val
checkVal = GET key
(then if checkVal != val:) UNWATCH
(otherwise:) EXEC
我還在學習更多有關Redis的知識,但我不太清楚這有什么好處。 難道你不想最終結果更像是這樣嗎?:
WATCH key
MULTI
val = GET key
val = val + 1
SET key $val
EXEC
或者SE.Redis的工作原理是不可能的?
不直接暴露WATCH
的原因是因為SE.Redis如何設計用於在單個連接上復用來自不同調用堆棧的命令。 這使得必須非常嚴格地管理任何事務工作。
我不清楚“未改變”的目的本身是什么 ,而不是與某些已知值相比 - 否則你只是創造了競爭條件。 肯定可以添加對它的支持,但我真的想先了解預期的用例。 你可以解釋嗎?
重新編輯; 你最喜歡的例子(最后一個例子) 與redis無法實現 - 與SE.Redis無關; 如果你在MULTI
進行GET
,那么在EXEC
完成之前你不會得到答案 - 所以你不可能使用SET
的值: 它還沒有 。
如果它不是用於多路復用,您可以重新訂購第二個示例(基於SE.Redis所做的):
WATCH key
val = GET key
MULTI
val = val + 1
SET key $val
EXEC
這是典型的利用WATCH
:你看 ,你事先查詢的東西,那么你知道{key}
這個循環過程中是不變的(或至少,該交易將已經退出;沒有不一致的狀態)。 但是, WATCH
與多路復用器不兼容 ,這就是為什么SE.Redis會強制您在事務之前獲取值的路徑,然后允許您比較該值以斷言它不變。 相同的結果; 方法略有不同,但它是多路復用器安全的。 有關該主題的更多信息, 請參見此處
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.