2015-05-29 54 views
1

我以前一直用這個:Redigo多請求

data, err := redis.Bytes(c.Do("GET", key)) 

,以確保返回的數據字節的片。

不過,我現在需要一個額外的命令添加到Redis的要求,所以我有這樣的事情:

c.Send("MULTI") 
c.Send("GET", key) 
c.Send("EXPIRE", key) 
r, err := c.Do("EXEC") 

,但現在我似乎無法使GET命令返回字節片。我試過像下面那樣加入redis.Bytes,但沒有運氣。

c.Send("MULTI") 
redis.Bytes(c.Send("GET", key)) 
c.Send("EXPIRE", key) 
r, err := c.Do("EXEC") 
+0

您看到什麼錯誤? – inf

回答

2

MULTI用於以原子方式來發送的Redis幾個命令,通過創建交易。這根本不是管道。

在撥打EXEC之前,沒有任何命令會實際執行,因此在事務中調用GET時無法獲得該值。

從文檔:

當Redis的連接是在多請求的情況下,所有命令將與字符串QUEUED答覆(發送作爲從視Redis的協議的點狀態應答)。 EXEC被調用時,排隊的命令被簡單地安排執行。

在redigo流水線被以不同的方式進行:

http://godoc.org/github.com/garyburd/redigo/redis#hdr-Pipelining

你想要做的是這樣的(未經測試):

c.Send("GET", key) 
c.Send("EXPIRE", key) 
c.Flush() 
v := redis.Bytes(c.Receive()) // reply from GET 
_, err = c.Receive() // reply from EXPIRE 
+0

是的好點 - 將標題更改爲更合適的內容。 – tommyd456

+0

我不同意你對修改的評論。讀一致性與寫一致性一樣重要,而Redis MULTI/EXEC塊可以確保兩者一致。絕對有使用情況需要在MULTI/EXEC塊中使用GET操作。 –

+0

@DidierSpezia指出並同意編輯 – SirDarius

2

在Redis的,該EXEC命令返回一個包含事務中所有命令結果的數組。

redigo提供Values函數,該函數將陣列命令回覆轉換爲[]interface{}

c.Send("MULTI") 
c.Send("GET", key) 
c.Send("EXPIRE", key) 
r, err := redis.Values(c.Do("EXEC")) 

r[0]現在已經從GET命令作爲interface{}的答覆,所以你需要做一個類型斷言得到字節的片你期待:

data := r[0].([]byte) 

參考

+0

請注意,如果您對redis和redigo的內部知識不是很熟悉,那麼也可以使用內置轉換函數並使用nil錯誤值進行二級轉換,這會更安全。在這個例子中,它看起來像這樣:'data:= redis.Bytes(r [0],nil)'。 – GrandOpener