大白話講解Redis的事務

一、介紹

Redis的事務並不像Mysql那麼靈活,有隔離級別,出問題後還能回滾數據等高級操作。Redis畢竟是非關係型數據庫,他目前事務回滾機制是不執行命令,也就是可以採取watch命令模擬樂觀鎖,進行監聽數據,發現數據不是事務開始時候的樣子了,那麼我這個事務裏的命令就不會得到執行。

二、三大命令

首先看下事務的全部命令
在這裏插入圖片描述
但核心的命令就三個

  • MULTI:開始事務。
  • EXEC:執行事務,也就是說只有EXEC命令執行的時候,這個事務內的語句纔會真正的得到執行。
  • WATCH:監聽數據變化,在開始事務之前執行。

三、實戰

1、MULTI/EXEC

1.1、描述

誰的exec先到達先處理誰的事務,比如有2個客戶端,第一個發送mutil開啓事務,然後執行了get k1操作,第二個客戶端同樣發送mutil開啓事務,然後執行了del k1操作。由於redis是單進程單線程的,所以這兩個client發送的命令執行肯定有先後順序,那麼哪個先執行呢?完全取決於exec命令,看exec命令哪個先到達先處理哪個。比如1的exec先到達,那就先get,然後client2的exec到了則在處理del。

1.2、圖示

在這裏插入圖片描述

1.3、代碼

# 先設置k1爲2
set k1 2

# 客戶端1
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> get k1
QUEUED

# 客戶端2
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> del k1
QUEUED

# 然後客戶端2執行exec
127.0.0.1:6380> EXEC
1) (integer) 1

# 然後客戶端1執行exec,結果發現nil了,被刪了。 類似於mysql中的讀已提交。不是RR。
127.0.0.1:6380> EXEC
1) (nil)

2、WATCH/MULTI/EXEC

2.1、描述

樂觀鎖的功能,比如先發送watch進行監聽到當前k1的值是3,然後開啓事務,執行 get k1,這時候 exec還沒執行,所以整個事務不會執行。在這期間client2執行了set k1 4(下圖是del語句,一樣的盜裏),且exec先到達執行完畢了。這時候client1再執行exec的時候發現k1的值已經變化了,則redis會爲我們回滾這條語句,不進行執行client1的事務。

2.2、圖示

在這裏插入圖片描述

2.3、代碼

set k1 2

# 客戶端1
127.0.0.1:6380> watch k1
OK
127.0.0.1:6380> MULTI 
OK
127.0.0.1:6380> set k1 5
QUEUED
127.0.0.1:6380> get k1
QUEUED

# 客戶端2
127.0.0.1:6380> MULTI
OK
127.0.0.1:6380> set k1 adasdad
QUEUED

# 提交客戶端2的事務
127.0.0.1:6380> exec
1) OK

# 提交客戶端1的事務,發現報錯了。redis裏面不會有異常,只會有語法錯誤,nil在這裏就可以理解這個事務沒執行,因爲他監測到k1數據變化了
127.0.0.1:6380> exec
(nil)

3、說明

  • 開啓事務後每次執行命令都返回一個QUEUE,代表開啓事務後每個命令都在queue裏,並沒有得到執行,exec後才執行
  • watch監聽到數據有變化,則命令不會執行。返回了nil,疑問:爲什麼nil不是事務裏命令的正常返回值呢? 我們事務裏兩個命令,他只返回了一個nil,有頭皮屑想也是命令沒得到執行。否則就返回兩條結果了。

四、總結

  • 介紹&&與mysql事務區別
  • WATCH/MULTI/EXEC的作用
  • 實戰
  • 事務開啓後,每次執行命令都是放到QUEUE

五、個人公衆號

微信公衆號【Java碼農社區】
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章