https://juejin.cn/post/6891158857708797959
首先Redis事務在實際的場景應用上也占著比較重要的地位,例如在秒殺場景中,我們就可以利用Redis事務中的watch命令監聽key,實現樂觀鎖,保證不會出現沖突,也防止商品超賣。
另外就是Redis事務也是面試過程中面試官著重照顧的基礎知識對象,假設面試官問你實現Redis事務有哪些方式?事務發生錯誤時Redis是怎么處理的?Redis事務支持回滾嗎等等這些問題,你是否能脫口而出回答上來呢?如果你對這方便的基礎知識有所欠缺,那是不是就栽跟頭了呢?
兩種實現方式
redis命令 MULTI、EXEC、DISCARD、WATCH
multi開啟事務
exec是執行
disccard是放棄事務返回
重點講下watch
WATCH 命令用于在事務開始之前監視任意數量的鍵,當調用 EXEC 命令執行事務時, 如果任意一個被監視的鍵已經被其他客戶端修改了, 那么整個事務不再執行, 直接返回失敗。
看例子:
- 首先我們在一個Redis客戶端一上使用 WATCH 命令監控兩個key,分別為name和sex,然后開啟事務,在事務中修改name的值,
- 在客戶端一執行 EXEC 命令之前,我們另外開一個客戶端二,在客戶端二中我們修改sex的值為man
接著我們回到客戶端一執行 EXEC 命令
# 客戶端一
127.0.0.1:6379> get name
"dashu"
127.0.0.1:6379> get sex
"male"
127.0.0.1:6379> WATCH name sex
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set name saycode
QUEUED
127.0.0.1:6379> EXEC
(nil) # 事務失敗
127.0.0.1:6379> get sex
"man"
127.0.0.1:6379> get name
"dashu"#--------- 這是一條分割線 ---------## 客戶端二
127.0.0.1:6379> get sex
"male"
127.0.0.1:6379> set sex man
OK
從上面執行的結果可以看到,客戶端一中的事務失敗了,事務中所修改的name的值也不成功。主要原因是:調用 EXEC 命令執行事務時,被監控的sex 被客戶端二修改了,所以客戶端一的事務不再執行
watch命令的原理 看 https://juejin.cn/post/6891158857708797959
Lua腳本
除了上面介紹的命令模式可以實現Redis事務外,其實還有一種非常重要的方式:Lua腳本。
為什么要夸Lua腳本呢?我們來看看Lua腳本有什么優勢:
原子操作:Redis確保腳本執行期間,其它任何腳本或者命令都無法執行。也就是說,在編寫腳本的過程中無需擔心會出現競態條件,無需使用事務。
減少網絡開銷:可以將多個請求通過腳本的形式一次發送,減少網絡時延。因此使用腳本要更簡單,速度更快
復用。客戶端發送的腳本會永久存在redis中,這樣,其他客戶端可以復用這一腳本而不需要使用代碼完成相同的邏輯。
香嗎?真香!反正用過的都說好。可以看到相比命令模式還是優勢還蠻大的。
那么Lua腳本要怎么用呢?下面跟大家介紹幾個常見的常用的命令:
EVAL
EVAL 可以理解為是lua腳本的解釋器,它的語法格式如下:
EVAL script numkeys key [key ...] arg [arg ...]
- script:一段 Lua 腳本或 Lua 腳本文件所在路徑及文件名。
- numkeys:Lua 腳本對應參數數量
- key [key …]:Lua 中通過全局變量 KEYS 數組存儲的傳入參數
- arg [arg …]:Lua 中通過全局變量 ARGV 數組存儲的傳入附加參數
官方腔有點重對吧,沒事,咱們來看個例子:
eval