2015-04-20 50 views
3

是否可以使用multi.incr(value)multi.hmsetRedis - 在交易中使用Incr值

我的意思是:

var name = 'Josh'; 
var multi = client.multi(); 
multi.incr('id'); // incr => 1 
multi.hmset('user:' + <need incr value here>, 'username', name); 
// I want multi.hmset('user:1', 'username', 'Josh'); 
multi.exec(function(err,data){ .. }); 

我的目標是增加「ID」,然後將其設置爲一個交易的用戶ID。我已閱讀,我需要做client.watch('id'),但我不明白如何使用它。

PD:請用後的代碼你的回答,是最好的方式:)

回答

13

上面接受的答案是不必要的複雜。在這種情況下,您不需要使用多功能或手錶。 INCR已經是原子性的,專爲這種確切的情況而設計。編輯:感謝Itamar Haber & robe007用於讓接受的答案改變。 :)

你可以簡單地這樣做:

var name = 'Josh'; 
client.incr('id', function(err, id) { 
    client.hmset('user:' + id, 'username', name); 
}); 

通過做好以上,INCR自動鎖定「ID」鍵,增加它的你,將其解鎖,並返回給你。因此,任何人都無法使用上面的代碼獲取重複的用戶ID。與WATCH/GET不同的是,它也具有永遠不會失敗的好處,在這種情況下,如果失敗,您必須檢查失敗並再次運行查詢。

+2

這應該是公認的答案 –

+0

@GeigeV完全 - 很樂意刪除我的,如果OP不接受它 –

+0

@ItamarHaber好的,讓我接受這個答案,但是,當我在2015年問這個問題時,你是唯一一個誰回答了我的問題,而且這些代碼也起作用。一如既往:Toda&Shalom! – robe007

2

UPDATE:本炸有好心指出,這個答案是「過於複雜」。我欣賞憐憫,但它應該被稱爲「簡單倒退」或「我在想什麼,如果有的話?」。請完全忽略下面的內容。

您無法執行INCR並在MULTI塊中獲得結果 - 您必須執行INCR塊才能實際運行(並返回結果)。相反,WATCH允許你嘗試樂觀的交易 - 如果WATCHed鍵被改變,它將失敗。因此,請考慮以下代碼:

var name = 'Josh'; 
client.watch('id'); 
client.get('id', function(err, data) { 
    var multi = client.multi(); 
    var id = int(data) + 1; 
    multi.hmset('user:' + id, 'username', name); 
    multi.incr('id'); 
    multi.exec(function(err,data){ 
    console.log(data); 
    }); 
}); 

首先,它在鍵上設置一個手錶並獲取其當前值。然後它建立一個事務並嘗試執行它。如果在此期間更改了ID,它將失敗,因此需要再次嘗試。 OTOH,這個流程可以確保你的id和user:id被正確處理。

+0

它有一個小問題:'var id = client.get('id')+ 1;'不返回'id'。我認爲這是get方法的回調。任何建議?,因爲我不想在那裏使用回調。 – robe007

+1

哦,對了,Node的回撥地獄......我會更新的。 –

+0

拜託,謝謝! – robe007