2014-11-06 33 views
2

我想用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的作品?

+0

我將編輯我的答案以反映您的編輯 – 2014-11-07 17:07:05

回答

0

WATCH沒有直接公開的原因是SE.Redis的設計是如何將來自不同調用堆棧的命令複用到單個連接上的。這使得任何交易工作都必須嚴格管理非常

我不清楚「不變」的目的是什麼本身,沒有比較一些已知的價值 - 否則你只是創造一個競爭條件。肯定有可能爲它添加支持,但我真的很想先理解預期的用例。你可以解釋嗎?


重新編輯;您的首選示例(最後一個)根本不可能with 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強制您在事務之前取回值的路線,然後允許您比較該值並聲明它未更改。同樣的結果;略有不同的方法,但它是多路複用器安全的。欲瞭解更多關於該主題see here

+0

感謝您的回覆,我更新了問題,希望能更好地解釋它。 – 2014-11-07 15:36:35

+0

好的,非常有幫助。我錯過的兩個鍵是1:你必須在'MULTI'之前得到'WATCH'ed值,否則它不起作用。 2:由於多路複用器,「不變」的概念並不真正起作用 - 你需要與之相比較。很高興知道。 – 2014-11-07 18:42:46

+0

另一個說明 - SE.Redis是一個非常棒的圖書館,感謝您的所有工作。 – 2014-11-07 18:45:25

相關問題