您好,登錄后才能下訂單哦!
這篇文章主要介紹Redis中事務是什么,文中介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們一定要看完!
命令 | 格式 | 作用 | 返回結果 |
---|---|---|---|
WATCH | WATCH key [key ...] | 將給出的Keys 標記為監測態 ,作為事務執行的條件 | always OK. |
UNWATCH | UNWATCH | 清除事務中Keys 的 監測態 ,如果調用了EXEC or DISCARD,則沒有必要再手動調用UNWATCH | always OK. |
MULTI | MULTI | 顯式 開啟redis事務 ,后續commands 將排隊,等候使用EXEC進行原子執行 | always OK. |
EXEC | EXEC | 執行事務中的commands 隊列,恢復連接狀態。如果WATCH在之前被調用,只有監測 中的Keys 沒有被修改,命令才會被執行,否則停止執行(詳見下文,CAS機制 ) | 成功: 返回數組 —— 每個元素對應著原子事務中一個 command 的返回結果;失敗: 返回 NULL (Ruby 返回`nil` ); |
DISCARD | DISCARD | 清除事務中的commands 隊列,恢復連接狀態。如果WATCH在之前被調用,釋放 監測 中的Keys | always OK. |
注意:
------
MULTI
,EXEC
,DISCARD
才是顯式
開啟并控制事務的常用命令,可類比關系型數據庫
中的BEGAIN
,COMMIT
,ROLLBACK
(事實上,差距很大);------
WATCH
命令的使用是為了解決事務并發
產生的不可重復讀
和幻讀
的問題(簡單理解為給Key加鎖
);
MULTI, EXEC, DISCARD and WATCH 是Redis事務的基礎。用來顯式開啟并控制一個事務,它們允許在一個步驟中執行一組命令
。并提供兩個重要的保證:
事務中的所有命令都會被序列化并按順序執行。在執行Redis事務的過程中,不會出現由另一個客戶端發出的請求。這保證 命令隊列
作為一個單獨的原子操作被執行。
隊列中的命令要么全部被處理,要么全部被忽略。EXEC命令觸發事務中所有命令的執行,因此,當客戶端在事務上下文中失去與服務器的連接,
如果發生在調用MULTI命令之前,則不執行任何commands
;
如果在此之前EXEC命令被調用,則所有的commands
都被執行。
同時,redis使用AOF(append-only file),使用一個額外的write操作
將事務寫入磁盤。如果發生宕機,進程奔潰等情況,可以使用redis-check-aof tool 修復append-only file,使服務正常啟動,并恢復部分操作。
使用MULTI
命令顯式開啟
Redis事務。 該命令總是以OK回應。此時用戶可以發出多個命令,Redis不會執行這些命令,而是將它們排隊
。EXEC
被調用后,所有的命令都會被執行。而調用DISCARD
可以清除
事務中的commands隊列
并退出事務
。
以下示例以原子方式,遞增鍵foo和bar。
>MULTI OK >INCR foo QUEUED >INCR bar QUEUED >EXEC 1)(整數)1 2)(整數)1
從上面的命令執行中可以看出,EXEC
返回一個數組
,其中每個元素都是事務中單個命令的返回結果,而且順序與命令的發出順序相同
。
當Redis連接處于MULTI
請求的上下文中時,所有命令將以字符串QUEUED
(從Redis協議的角度作為狀態回復發送)作為回復,并在命令隊列
中排隊。只有EXEC被調用時,排隊的命令才會被執行,此時才會有真正的返回結果
。
事務期間,可能會遇到兩種命令錯誤:
在調用EXEC
命令之前出現錯誤(COMMAND
排隊失敗)。
例如,命令可能存在語法錯誤
(參數數量錯誤,錯誤的命令名稱...);
或者可能存在某些關鍵條件
,如內存不足的情況(如果服務器使用maxmemory
指令做了內存限制
)。
客戶端會在EXEC
調用之前檢測第一種錯誤。 通過檢查排隊命令的狀態回復
(***注意:這里是指排隊
的狀態回復
,而不是執行結果
***),如果命令使用QUEUED
進行響應,則它已正確排隊,否則Redis將返回錯誤。如果排隊命令時發生錯誤,大多數客戶端將中止該事務并清除命令隊列
。然而:
在Redis 2.6.5之前
,這種情況下,在EXEC
命令調用后,客戶端會執行命令的子集(成功排隊的命令)而忽略之前的錯誤。
從Redis 2.6.5開始
,服務端會記住在累積命令期間發生的錯誤,當EXEC
命令調用時,將拒絕執行事務,并返回這些錯誤,同時自動清除命令隊列
。
示例如下:
>MULTI +OK >INCR a b c -ERR wrong number of arguments for 'incr' command
這是由于
INCR
命令的語法錯誤,將在調用EXEC
之前被檢測出來,并終止事務(version2.6.5+)。
在調用EXEC
命令之后出現錯誤。
例如,使用錯誤的值
對某個key
執行操作(如針對String
值調用List
操作)
EXEC
命令執行之后發生的錯誤并不會被特殊對待:即使事務中的某些命令執行失敗,其他命令仍會被正常執行
。
示例如下:
>MULTI +OK >SET a 3 +QUEUED >LPOP a +QUEUED >EXEC *2 +OK -ERR Operation against a key holding the wrong kind of value
EXEC
返回一個包含兩個元素的字符串數組,一個元素是OK
,另一個是-ERR……
。能否將錯誤合理的反饋給用戶這取決于
客戶端library
(如:Spring-data-redis.redisTemplate
)的自身實現。需要注意的是,即使命令失敗,隊列中的所有其他命令也會被處理----Redis不會停止命令的處理。
重點
)事實上Redis命令
在事務執行時可能會失敗,但仍會繼續執行剩余命令
而不是Rollback
(事務回滾)。如果你使用過關系數據庫
,這種情況可能會讓你感到很奇怪。然而針對這種情況具備很好的解釋:
Redis命令
可能會執行失敗,僅僅是由于錯誤的語法被調用(命令排隊時檢測不出來的錯誤),或者使用錯誤的數據類型操作某個Key
: 這意味著,實際上失敗的命令都是編程錯誤造成的,都是開發中能夠被檢測出來的,生產環境中不應該存在。(這番話,徹底甩鍋,“都是你們自己編程錯誤,與我們無關”。)
由于不必支持Rollback
,Redis
內部簡潔并且更加高效。
“如果錯誤就是發生了呢?”這是一個反對Redis
觀點的爭論
。然而應該指出的是,通常情況下,回滾并不能挽救編程錯誤。鑒于沒有人能夠挽救程序員的錯誤,并且Redis命令
失敗所需的錯誤類型不太可能進入生產環境,所以我們選擇了不支持錯誤回滾(Rollback)這種更簡單快捷的方法。
DISCARD
被用來中止事務。事務中的所有命令將不會被執行,連接將恢復正常狀態。
> SET foo 1 OK > MULTI OK > INCR foo QUEUED > DISCARD OK > GET foo "1"
以上是“Redis中事務是什么”這篇文章的所有內容,感謝各位的閱讀!希望分享的內容對大家有幫助,更多相關知識,歡迎關注億速云行業資訊頻道!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。