是的,我們今天要來討論一下 Redis 的 transaction。我們知道 Transaction 要嘛全執行要嘛全不執行,Redis 在 2.2 之後提供了 optimistic lock,讓我們得以進行 check-and-set 的可能,並且實作了幾個方法讓我們可以達成 transaction 的需求。
Docker run redis
> docker pull redis
> docker run --name cache -p 6379:6379 -d redis
開啟 transaction,回傳 OK
表示可以開始接受命令檢查
> MULTI
OK
在執行 MULTI
開始帶入想要執行的命令,在確認命令都可以被執行後,送出 commit 的命令便是 EXEC
> MULTI
OK
> INCR foo
QUEUED
> INCR bar
QUEUED
> EXEC
1) (integer) 1
2) (integer) 1
在執行 MULTI
開始帶入想要執行的命令,但確認命令不符合預期時,用 DISCARD
取消所有準備操作的命令
> MULTI
OK
> INCR a
QUEUED
> INCR a b c
-ERR wrong number of arguments for 'incr' command
> DISCARD
OK
> GET a
"1"
針對特定 key 進行監控,如果被監控的 key 被異動過,則執行 EXEC
時會失敗
> SET mykey 0
OK
> WATCH mykey
OK
> SET mykey 1
OK
> MULTI
OK
> SET mykey 2
QUEUED
> EXEC
(nil)
> GET mykey
"1"
我們必須了解到 Redis transaction,能夠被實現的條件是基於 check-and-set 的 two-phase commit,而 check-and-set 則是因 Redis 2.2 後有 optimistic lock 得以實作。其中 WATCH
便是我們的 optimistic lock 實作出的方法,針對單一 key value 進行監控,配合 EXEC
確保本次 transaction 的原子性(atomic),保證我們這一系列的操作都可以如預期地被完成。關於 Redis transaction 的說明官方提供很詳細的解釋與範例。