multi事務 watch命令

2021-06-22 21:33:05 字數 2089 閱讀 3578

本文章是個人筆記,由學習multi

okredis>sadd "user:1:following" 2

queued

redis>sadd "user:2:followers" 1

queued

redis>exec

1) (integer) 1

2) (integer) 1

上面的**演示了事務的使用方式。首先使用multi命令告訴redis:「下面我發給你的命令屬於同乙個事務,你先不要執行,而是把它們暫時存起來。」redis回答:「ok。」而後我們傳送了兩個sadd命令來實現關注和被關注操作,可以看到redis遵守了承諾,沒有執行這些命令,而是返回queued表示這兩條命令已經進入等待執行的事務佇列中了。

當把所有要在同乙個事務中執行的命令都發給redis後,我們使用exec命令告訴redis將等待執行的事務佇列中的所有命令(即剛才所有返回queued的命令)按照傳送順序依次執行。exec命令的返回值就是這些命令的返回值組成的列表,返回值順序和命令的順序相同。

redis保證乙個事務中的所有命令要麼都執行,要麼都不執行。如果在傳送exec命令前客戶端斷線了,則redis會清空事務佇列,事務中的所有命令都不會執行。而一旦客戶端傳送了exec命令,所有的命令就都會被執行,即使此後客戶端斷線也沒關係,因為redis中已經記錄了所有要執行的命令。

除此之外,redis的事務還能保證乙個事務內的命令依次執行而不被其他命令插入。試想客戶端a需要執行幾條命令,同時客戶端b傳送了一條命令,如果不使用事務,則客戶端b的命

令可能會插入到客戶端a的幾條命令中執行。如果不希望發生這種情況,也可以使用事務。

我們已經知道在乙個事務中只有當所有命令都依次執行完後才能得到每個結果的返回值,可是有些情況下需要先獲得一條命令的返回值,然後再根據這個值執行下一條命令。例如,介紹incr命令時曾經說過使用get和set命令自己實現incr函式會出現競態條件,偽**如下:

def incr( key)

value=get key

if not value

value=0

value= value+1

set key, value

return value

肯定會有很多讀者想到可以用事務來實現incr函式以防止競態條件,可是

因為事務中的每個命令的執行結果都是最後一起返回的,所以無法將前一條命令的結果作為下一條命令的引數,即在執行set命令時無法獲得get命令的返回值,也就無法做到增1的功能了。

為了解決這個問題,我們需要換一種思路。即在get獲得鍵值後保證該鍵值不被其他客戶端修改,直到函式執行完成後才允許其他客戶端修改該鍵鍵值,這樣也可以防止競態條件。

要實現這一思路需要請出事務家族的另一位成員:watch。

watch命令可以監控乙個或多個鍵,一旦其中有乙個鍵被修改(或刪除),之後的事務就不會執行。監控一直持續到exec命令(事務中的命令是在exec之後才執行的,所以在multi命令後可以修改watch監控的鍵值),如:

redis>set key 1

okredis>watch key

okredis>set key 2

okredis>multi

okredis>set key 3

queued

redis>exec

(nil)

redis>get key

"2"

上例中在執行watch命令後、事務執行前修改了key的值(即set key 2),所以最後事務中的命令set key 3沒有執行,exec命令返回空結果。

學會了watch命令就可以通過事務自己實現incr函式了,偽**如下:

def incr( key)

watch key

value=get key

if not value

value=0

value= value+1

multi

set key, value

result=exec

return result[0]

but,watch只能防止之後乙個事務的執行.而不能保證其他客戶端不修改這一鍵值.

Redis 事務 Multi和CAS 的實現

redis也有事務的功能,但是這個事務可能跟mysql之類的rdbms不同。官網上的 transactions 介紹了redis中的事務。redis中使用multi和exec命令設定事務邊界,discard在multi命令提交後可丟棄事務。另外watch命令可以實現cas操作。redis中的事務歸納...

Reids基礎事務以及watch監控事務和回滾

redis也是有事務的 redis執行事務的三個過程 1.開啟事務 multi 2.命令進入佇列 3.執行事務 exec如果要求在乙個連線中,在spring會使用sessioncallback介面來處理。這是為了減少效能損耗 redis的基礎事務 multi開啟事務,直到exec執行事務,期間的命令...

Redis事務使用方法 watch

redis事務是一組命令的集合,也是redis的最小執行單位之一。乙個事務的所有命令,要麼都執行,要麼都不執行。redis能保證事務執行期間不會有其他命令插入。命令格式 說明discard discard 取消事務 exec exec 執行事務中的命令 multi multi 標記乙個事務的開始 u...