Redis事務(wù)深入解析

Redis 事務(wù)介紹

  1. Redis 的事務(wù)是通過 MULTI,EXEC,DISCARD 和 WATCH 這四個命令來完成的。
  2. Redis 的單個命令都是原子性的,所以這里確保事務(wù)性的對象是命令集合。
  3. Redis 將命令集合序列化并確保處于同一事務(wù)的命令集合連續(xù)且不被打斷的執(zhí)行
  4. Redis不支持回滾操作

相關(guān)命令

image.png

在介紹 Redis 事務(wù)相關(guān)命令前,我們先上一張圖,這張圖很好的描述了 Redis 事務(wù)的執(zhí)行過程,在圖里體現(xiàn)了部分命令,WATCH 命令會在后面單獨介紹,需要注意的一點是這張圖里面的 queue 隊列,理解它的作用,然后再結(jié)合相關(guān)命令的介紹,就能夠很快搞明白 Redis 事務(wù)。

1)MULTI:用于標(biāo)記事務(wù)塊的開始。Redis 會將后續(xù)的命令逐個放入隊列中,然后使用 EXEC 命令原子化地執(zhí)行這個命令序列。

127.0.0.1:6379> multi # 開啟事務(wù)
OK
127.0.0.1:6379> set k1 alan # 設(shè)置 k1
QUEUED # k1 加入隊列
127.0.0.1:6379> set k2 tom # 設(shè)置 k2
QUEUED # k2 加入隊列

2)EXEC:在一個事務(wù)中執(zhí)行所有先前放入隊列的命令,然后恢復(fù)正常的連接狀態(tài)。

127.0.0.1:6379> exec
1) OK
2) OK

使用 EXEC 命令原子化地執(zhí)行這個命令序列,剛剛我們設(shè)置了 k1 和 k2 兩條命令,執(zhí)行EXEC 命令后,給我們反饋了兩個 OK,說明上述兩條命令全部執(zhí)行成功。

3)DISCARD:清除所有先前在一個事務(wù)中放入隊列的命令,然后恢復(fù)正常的連接狀態(tài)。

127.0.0.1:6379> multi
OK
127.0.0.1:6379> set k3 lucy
QUEUED
127.0.0.1:6379> set k4 jack
QUEUED
127.0.0.1:6379> discard
OK

4)WATCH:當(dāng)某個事務(wù)需要按條件執(zhí)行時,就要使用這個命令將給定的鍵設(shè)置為受監(jiān)控的狀態(tài)。注意:使用該命令可以實現(xiàn) Redis 的樂觀鎖。

(1)對于 WATCH 命令的演示就稍微麻煩一些,這里我們在 Xshell 中開啟兩個 ssh 渠道,并且都連接到了單機(jī)的 Redis 服務(wù)(兩個 ssh 渠道連接的是同一個 Redis 服務(wù))


在這里插入圖片描述

(2)在第一個窗口中使用 WATCH 命令,監(jiān)控 data1,并開啟事務(wù),添加設(shè)置 data2 的命令到命令隊列中


在這里插入圖片描述

(3)然后在第二個窗口中,改變 data1 的值


在這里插入圖片描述

(4)回到第一個窗口,執(zhí)行 EXEC 命令,此時會發(fā)現(xiàn)返回了一個 nil,而且我們獲取 data2 的值,返回的也是 nil,這就說明,當(dāng)被監(jiān)控的數(shù)據(jù)發(fā)生改變后,開啟的事務(wù)執(zhí)行是無法成功的,只有被監(jiān)控的數(shù)據(jù)不發(fā)生變化,事務(wù)才能正常執(zhí)行。
在這里插入圖片描述

5)UNWATCH:清除所有先前為一個事務(wù)監(jiān)控的鍵。

3、事務(wù)失敗處理

1)Redis 語法錯誤(可以理解為編譯期錯誤)


在這里插入圖片描述

在一個事務(wù)中,當(dāng)命令出現(xiàn)錯誤時,后續(xù)命令正確依舊是可以添加到命令隊列中去得,但是使用 EXEC 命令執(zhí)行命令隊列的時候,就會報錯,并且隊列中正確的命令也不會被執(zhí)行。

2)Redis 類型錯誤(可以理解為運行期錯誤)
在這里插入圖片描述

這種錯誤不是命令錯誤,而是因為對命令理解不透徹出現(xiàn)的使用錯誤,在執(zhí)行過程中會報錯,因為 username1 不是 list 類型,它只是一個 string 類型。有一點需要注意,從結(jié)果可以看出,第一條命令是執(zhí)行成功了的,所有我們使用"get username1"命令,返回了"alan"結(jié)果,這也證明了 Redis 是不支持事務(wù)回滾的。

3)為什么 Redis 不支持事務(wù)回滾?

(1)大多數(shù)事務(wù)失敗是因為語法錯誤或者類型錯誤,這兩種錯誤,在開發(fā)階段都是可以預(yù)見的。

(2)Redis 為了性能方面就忽略了事務(wù)回滾。

Linux、C/C++技術(shù)交流群:整理了一些C/C++ Linux服務(wù)器架構(gòu)師學(xué)習(xí)資料(加群獲?。ㄙY料包括C/C++,Linux,golang技術(shù),Nginx,ZeroMQ,MySQL,Redis,fastdfs,MongoDB,ZK,流媒體,CDN,P2P,K8S,Docker,TCP/IP,協(xié)程,DPDK,ffmpeg等),免費分享

在這里插入圖片描述

想要搞明白 Redis 事務(wù),一定要先理解文中那張圖解,了解 queue 命令隊列,以及各個命令是如何操作命令隊列的,還要特別注意 WATCH 命令,了解它的運行原理以及使用場景,最為重要的是一定要知道 Redis 事務(wù)失敗后是如何處理的,分為了兩種情況,還要能說明為什么 Redis 是不支持事務(wù)回滾的,了解了這些東西就 OK 了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容