1. 程式人生 > >Redis學習筆記06Redis命令之(5)事務

Redis學習筆記06Redis命令之(5)事務

mman 客戶 cau 連接 discard 順序 strong 存在 執行命令

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

multiexec之間的所有命令提交執行。

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命令時,multiexec之間的命令將被順序執行,而且是當做一個命令整體執行的,在這些命令執行過程中,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)

multiexecdiscard之間執行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

取消對所有被觀察的鍵的觀察。

執行execdiscard將自動執行unwatch,即自動取消對所有被觀察的鍵的觀察。

當執行了watch的連接斷開之後,自動unwatch

redis.coe2coe.me:6379> unwatch

OK

Redis學習筆記06Redis命令之(5)事務