天天看點

Redis教程10(事務)

redis是NOSQL資料庫,是以也存在事務,隻是此事務和關系型資料庫的事務是有差別的。

事務執行個體

Redis中事務的使用其實非常簡單,通過MULTI指令即可。

127.0.0.1:6379> multi
OK      

在MULTI指令執行之後,我們可以繼續發送指令執行,但此時指令不會立即執行,而是保持到一個隊列中,如下

127.0.0.1:6379> set k1 bbb
QUEUED
127.0.0.1:6379> set k2 ccc
QUEUED
127.0.0.1:6379> set k3 ddd
QUEUED
127.0.0.1:6379> set k4 eee
QUEUED
127.0.0.1:6379> get k1
QUEUED      

當所有的指令都輸入完成後,我們可以輸入EXEC指令來執行隊列中的指令,如下

127.0.0.1:6379> exec
1) OK
2) OK
3) OK
4) OK
5) "bbb"      

事務異常

事務中的異常有兩種情況:

進入隊列之前發生錯誤

比較常見的指令錯誤,此類異常redis的處理方式是,伺服器會對進入隊列失敗的情況進行記錄,在執行exec指令送出的時候,對于該指令不會執行并放棄這個事務,如下

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set kk1 a
QUEUED
127.0.0.1:6379> set kk2 b
QUEUED
127.0.0.1:6379> set kk3 c 1 2  # 指令出錯
QUEUED
127.0.0.1:6379> set kk4 d
QUEUED
127.0.0.1:6379> exec
1) OK
2) OK
3) (error) ERR syntax error # 執行指令的時候錯誤提示
4) OK
127.0.0.1:6379> keys kk*
1) "kk1"
2) "kk2"
3) "kk4"      

注意 redis事務中有一個異常并不會造成其他指令的復原!

執行exec指令後發生的異常

對于這種情況,redis中也不會做特别的處理。事務中的指令繼續執行

127.0.0.1:6379> set c1 aaa
QUEUED
127.0.0.1:6379> incr c1
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) ERR value is not an integer or out of range      

不同于關系型資料庫,redis中沒有復原操作,官方解釋是:

Redis 指令隻會因為錯誤的文法而失敗(并且這些問題不能在入隊時發現),或是指令用在了錯誤類型的鍵上面:這也就是說,從實用性的角度來說,失敗的指令是由程式設計錯誤造成的,而這些錯誤應該在開發的過程中被發現,而不應該出現在生産環境中。

因為不需要對復原進行支援,是以 Redis 的内部可以保持簡單且快速

Watch

watch指令可以監控一個或多個鍵,一旦其中有一個鍵被修改(或删除),之後的事務就不會執行。監控一直持續到exec指令(事務中的指令是在exec之後才執行的,是以在multi指令後可以修改watch監控的鍵值)。假設我們通過watch指令在事務執行之前監控了多個Keys,倘若在watch之後有任何Key的值發生了變化,exec指令執行的事務都将被放棄,同時傳回Null multi-bulk應答以通知調用者事務執行失敗。

127.0.0.1:6379> set b2 bbb
OK
127.0.0.1:6379> watch b2
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set b2 d111
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> set b3 bbb
OK
127.0.0.1:6379> watch b3
OK
127.0.0.1:6379> set b3 aaaa
OK
127.0.0.1:6379> set b3 avava
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set b3 aaaa
QUEUED
127.0.0.1:6379> exec
(nil)      

exec後會自動執行unwatch指令,撤銷監控

UnWatch

撤銷對一個key的監控

127.0.0.1:6379> set n1 aaa
OK
127.0.0.1:6379> watch n1
OK
127.0.0.1:6379> set n1 bbbb
OK
127.0.0.1:6379> unwatch
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set n1 bbbb
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get n1
"bbbb"      

~ok 事務到此為止