標籤:style blog color 使用 ar strong 資料 div sp
一、事務
Redis 的事務功能允許使用者將多個命令包裹起來,然後一次性地、按順序地執行被包裹的所有命令。在事務執行的過程中,伺服器不會中斷事務而改去執行其他命令請求,只有在事務包裹的所有命令都
被執行完畢之後,伺服器才會去處理其他命令請求。
事務樣本:
現在, 讓我們假設 SETEX 命令並不存在於 Redis , 並且 SET 命令也不支援 EX seconds 參數, 如果我們要自己來實現一個 SETEX 命令的話, 那麼我們可能會使用以下代碼:
def SETEX(key, seconds, value):SET key valueEXPIRE key seconds
在一般情況下,這個自製的 SETEX 命令可以達到設定索引值對並設定生產時間的效果,但是這個自製的SETEX 存在一個缺陷:如果伺服器在成功地執行 SET 命令並儲存資料之後崩潰,那麼 EXPIRE 命令將沒辦法執行。
這時雖然我們已經設定了鍵, 但並沒有為鍵設定到期時間, 如果我們沒有發覺的話, 那麼這個本來應該定期被刪除的鍵就會一直留在資料庫裡面佔用著記憶體, 甚至造成之後的程式出錯。
二、事務命令
為了避免遇上以上所說的情況, 我們需要用到 Redis 的事務功能, 通過事務, 我們可以讓 Redis一次性地執行多個命令, 並且確保事務中的命令要麼就全部都執行,要麼就一個都不執行。
MULTI : 開始一個新的事務
DISCARD : 放棄事務
EXEC : 執行事務中所有命令
以下分別對事務命令進行描述:
MULTI
開始一個事務。
在這個命令執行之後,用戶端發送的所有針對資料庫或者資料庫鍵的命令都不會被立即執行,而是被放入到一個事務隊列裡面,並返回 QUEUED 表示命令已入隊。
redis> MULTI # 開始一個事務OKredis> SET msg "hello world" # 將這個 SET 命令放入事務隊列QUEUEDredis> EXPIRE msg 10086 # 將這個 SET 命令放入事務隊列QUEUED
DISCARD
取消事務,放棄執行事務隊列中的所有命令。
redis> MULTIOKredis> SET msg "hello world"QUEUEDredis> EXPIRE msg 10086QUEUEDredis> DISCARD # 事務已被取消OKredis> SET msg "hello world"OK
EXEC
執行事務,按照命令被入隊到事務隊列中的順序,執行事務隊列中的所有命令。命令的傳回值是一個列表,列表裡包含了事務隊列中所有被執行命令的傳回值。
redis> MULTIOKredis> SET msg "hello world"QUEUEDredis> EXPIRE msg 10086QUEUEDredis> EXEC1) OK # SET 命令的傳回值2) (integer) 1 # EXPIRE 命令的傳回值
使用事務保證操作的安全性
之前的自製 SETEX 的定義,帶有安全缺陷:
def SETEX(key, seconds, value):SET key valueEXPIRE key seconds # 如果伺服器在 SET 命令執行之後崩潰,那麼 EXPIRE 將無法執行
使用事務實現的自製 SETEX 的定義,沒有安全缺陷,伺服器保證要麼兩個命令都執行,要麼就兩個命令都不執行:
def SETEX(key, seconds, value):MULTISET key valueEXPIRE key secondsEXEC
三、流水線和事務的區別
流水線:確保多條命令會被一起發送;
事 務 :確保多條命令會被一起執行;
(PIPELINE_START)SET msg “hello world” # 這兩條命令會被一起發送至伺服器EXPIRE msg 10086(PIPELINE_END)
MULTISET msg “hello world” # 這兩條命令會一起被伺服器執行EXPIRE msg 10086EXEC
Redis附加功能之Redis事務