Redis學習筆記06Redis命令之(5)事務
1.1.1. multi
開始一個新事務。
redis.coe2coe.me:6379> multi
OK
執行此命令後,後面執行的set等命令將被緩存,直到被discard命令取消,或者被exec命令提交執行。
一旦執行了multi,再執行的命令,將被緩存到一個執行隊列中,而不是立即執行。因此這些命令的執行的結果,再其它客戶端連接中是看不到的。
比如:
在連接1中:
redis.coe2coe.me:6379> select 0
OK
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set a 1
QUEUED
返回值QUEUED表示當前命令並未執行,只是緩存到了執行隊列中。因此鍵a在其它連接中不可見。
redis.coe2coe.me:6379> get a
QUEUED
redis.coe2coe.me:6379> get host
QUEUED
在連接2中:
redis.coe2coe.me:6379> select 0
OK
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
redis.coe2coe.me:6379> get a
(nil)
在連接1執行exec提交執行之前,鍵a是不可見的。
redis.coe2coe.me:6379> get host
"redis.coe2coe.me"
查詢事務開始之前已經存在的鍵,是可以成功的。
1.1.2. discard
discard命令取消從最近的multi命令到discard之間的所有命令,這些命令將不會被執行,數據也不會被修改。
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
redis.coe2coe.me:6379> get host
"redis.coe2coe.me"
redis.coe2coe.me:6379> get port
"6379"
redis.coe2coe.me:6379> multi
OK
開啟事務成功。
redis.coe2coe.me:6379> set a 1
QUEUED
這個命令暫時未執行,而是被加到隊列中。
redis.coe2coe.me:6379> set b 1
QUEUED
redis.coe2coe.me:6379> set c 1
QUEUED
redis.coe2coe.me:6379> discard
OK
取消所有命令,清空執行隊列。
redis.coe2coe.me:6379> keys *
1) "port"
2) "host"
再次檢查鍵的集合,發現鍵a,b,c並沒有增加到數據庫中。
如果沒有執行MULTI就執行DISCARD,則報錯。
redis.coe2coe.me:6379> discard
(error) ERR DISCARD without MULTI
1.1.3. exec
將multi到exec之間的所有命令提交執行。
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set host redis101.coe2coe.me
QUEUED
redis.coe2coe.me:6379> set a 1
QUEUED
redis.coe2coe.me:6379> set b 1
QUEUED
redis.coe2coe.me:6379> exec
1) OK
2) OK
3) OK
redis.coe2coe.me:6379> keys *
1) "port"
2) "b"
3) "a"
4) "host"
發現增加了a,b兩個鍵。
redis.coe2coe.me:6379> get host
"redis101.coe2coe.me"
發現host這個鍵的值被修改了。
Redis事務的特點:
(1)原子性。
在執行exec命令時,multi和exec之間的命令將被順序執行,而且是當做一個命令整體執行的,在這些命令執行過程中,Redis確保不會穿插執行其它客戶端連接發送的命令。
這些命令要麽全部被執行,要麽一個也不執行。
(2)出錯則取消
如果有一個命令格式不正確,則稍後執行exec時將取消所有命令,即使其中包含一些正確的可執行命令。
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set a,3,4
(error) ERR wrong number of arguments for ‘set‘ command
redis.coe2coe.me:6379> set b 4
QUEUED
redis.coe2coe.me:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
1.1.4. watch
觀察一個鍵的值,檢測是否被其它客戶端連接修改了。
連接1:
redis.coe2coe.me:6379> set a 1
OK
redis.coe2coe.me:6379> get a
"1"
redis.coe2coe.me:6379> watch a
OK
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> set b 1
QUEUED
此時,在連接2中執行如下命令:
redis.coe2coe.me:6379> set a 2
OK
此時,再到連接1中執行如下命令:
redis.coe2coe.me:6379> exec
(nil)
返回值nil表明事務執行出錯了,即所有語句都沒執行。
redis.coe2coe.me:6379> get a
"2"
redis.coe2coe.me:6379> get b
(nil)
在multi和exec或discard之間執行watch會導致出錯。
redis.coe2coe.me:6379> multi
OK
redis.coe2coe.me:6379> watch a
(error) ERR WATCH inside MULTI is not allowed
1.1.5. unwatch
取消對所有被觀察的鍵的觀察。
執行exec和discard將自動執行unwatch,即自動取消對所有被觀察的鍵的觀察。
當執行了watch的連接斷開之後,自動unwatch。
redis.coe2coe.me:6379> unwatch
OK
Redis學習筆記06Redis命令之(5)事務