1. 程式人生 > 實用技巧 >Redis 事務

Redis 事務

Redis事務

Redis的事務是一組命令的集合。事務同命令一樣都是Redis的最小執行單元,一個事務中的命令,要麼全部執行,要麼都不執行。

Redis事務的原理

事務的原理是將一個事務的命令傳送給Redis,然後在讓Redis依次執行這些命令。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> sadd user:1:following 2
QUEUED
127.0.0.1:6379> sadd user:2:followers 1
QUEUED
127.0.0.1:6379> exec
1) (integer) 1
2) (integer) 1

首先multi命令告訴Redis, 下面我傳送給你的命令屬於同一事務,你先不要執行,而且先把他們暫存起來。
當把所有要在同一事務中執行的命令都發送給Redis後, 我們使用exec告訴Redis將等待執行的事務佇列的所有命令按照發送順序依次執行
Redis保證同一事務的所有命令,要麼全部執行,要麼都不執行。如果在傳送exec命令前客戶端斷了,則Redis會清空事務佇列,事務中的所有命令都不執行,一旦客戶端傳送了exec命令,所有的命令都會被執行,即使客戶端斷線也沒關係,因為Redis已經記錄所有要執行的命令。
Redis還能保證一個事務內的命令依次執行,不會被其他命令插入。

Redis事務錯誤處理

如果一個事務中的某個命令出錯了,Redis會怎麼處理?
1、語法錯誤。語法錯誤指命令不存在或者引數的個數不對。只要有一個命令有語法錯誤, 執行exec命令後Redis就會直接返回錯誤,連正確語法的命令都不會執行。
2、執行錯誤。執行錯誤指命令在執行時出現錯誤,比如使用雜湊型別的命令執行集合型別的鍵,這種錯誤在實際執行之前Redis是無法發現的,所以在事務中這樣的命令會被Redis接受並執行。如果事務中的一條命令出現執行錯誤,事務的其他命令會依然執行。
3、Redis事務沒有關係型資料庫提供的回滾功能,故開發者必須在事務執行出錯後收拾自己的爛攤子(將資料庫復原到事務執行前的狀態)

watch命令

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

127.0.0.1:6379> set key 1
OK
127.0.0.1:6379> watch key
OK
127.0.0.1:6379> multi 
OK
127.0.0.1:6379> set key 3
QUEUED
127.0.0.1:6379> exec
1) OK
127.0.0.1:6379> get key
"3"

我們知道一個事務中只有當所有命令都一次執行完後才能得到每個結果的返回值,但是在某些情況下,需要先獲得一條命令的返回值,然後根據這個值執行下一條命令, 如incr命令使用get和set命令自己實現incr命令會出現競態條件,虛擬碼如下

def incr($key):
    $value = get $key
    if not $value
        $value = 0
    $value = $value + 1
    set $key $value
    return $value

為了解決這個問題,Redis事務的另一個命令watch
執行了exec後會取消對所有鍵的監控,如果不想執行事務中的命令,也可以使用unwatch命令來取消監控。