01給女朋友講講Redis-事務

一、Redis事務的本質

一組命令的集合,一個事務中的所有命令都會被序列化,在事務執(zhí)行過程中,會按照順序執(zhí)行。

------頭部 -> set -> set -> set -> 尾部------

特性:

  • 一次性
  • 順序性
  • 排他性

Redis事務沒有隔離級別的概念。
Redis單條指令是保證原子性的,但是事務不保證原子性。

二、Redis事務實踐

主要命令如下:

  • MULTI ->開啟事務
  • EXEC ->執(zhí)行事務
  • DISCARD ->放棄事務

執(zhí)行效果如下所示
1.正常執(zhí)行事務

127.0.0.1:6379> MULTI #開啟事務
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> get k1
QUEUED
127.0.0.1:6379> get k2
QUEUED
127.0.0.1:6379> EXEC #執(zhí)行事務
1) OK
2) OK
3) "v1"
4) "v2"
127.0.0.1:6379>

2.放棄當前事務

127.0.0.1:6379> MULTI #開啟事務
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> set k2 v2
QUEUED
127.0.0.1:6379> DISCARD #放棄事務
OK
127.0.0.1:6379> get k1 #事務已經(jīng)被放棄,不會取到值
(nil)
127.0.0.1:6379> get k2
(nil)

3.編譯時發(fā)生錯誤
當事務開啟之后,多條命令中包含一條不存在的命令,本次事務會全部放棄。

127.0.0.1:6379> MULTI #開啟事務
OK
127.0.0.1:6379> set k1 v1
QUEUED
127.0.0.1:6379> setget k2 v2 #此處故意輸入錯誤命令,編譯時已經(jīng)報錯
(error) ERR unknown command `setget`, with args beginning with: `k2`, `v2`, 
127.0.0.1:6379> EXEC #執(zhí)行事務,事務全部放棄,不會成功
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get k1 #沒有取到編譯錯誤之前設置的值
(nil)

4.執(zhí)行時發(fā)生錯誤
當事務開啟之后,某些命令執(zhí)行了不合理的操作,那么該命令不會生效,但不影響本次事務中其他命令的執(zhí)行。

127.0.0.1:6379> set k1 wuhan
OK
127.0.0.1:6379> get k1
"wuhan"
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> set k2 shanghai
QUEUED
127.0.0.1:6379> INCR k1
QUEUED
127.0.0.1:6379> set k3 beijing
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) (error) ERR value is not an integer or out of range #此處k1不是數(shù)字,執(zhí)行incr會報錯
3) OK
127.0.0.1:6379> get k1
"wuhan"
127.0.0.1:6379> get k2 #雖然執(zhí)行命令INCR k1時出錯,沒有影響其余正常命令的執(zhí)行
"shanghai"
127.0.0.1:6379> get k3
"beijing"

三、Redis實現(xiàn)樂觀鎖

樂觀鎖

  • 做事很樂觀,認為什么時候都不會出問題,所以不會真正上鎖。在更新數(shù)據(jù)的時候去判斷一下,在此期間內(nèi)是否有人修改過數(shù)據(jù)。
  • 獲取version
  • 更新的時候比較version
    Redis中如何實現(xiàn)?
WATCH key [key ...]

在操作之前監(jiān)視指定的key,如果事務執(zhí)行期間被別的線程修改過,那么整個事務將會失效。
線程1:

127.0.0.1:6379> set money 1000 #假設賬戶有1000元
OK
127.0.0.1:6379> WATCH money #取之前先監(jiān)視key
OK
127.0.0.1:6379> MULTI #開啟事務
OK
127.0.0.1:6379(TX)> DECRBY money 500 #取500
QUEUED
127.0.0.1:6379(TX)> EXEC #執(zhí)行事務,返回結果為(nil),代表事務執(zhí)行失敗
(nil)
127.0.0.1:6379> get money #查看金額已經(jīng)發(fā)生變動
"600"

線程2:

127.0.0.1:6379> get money #賬戶起始金額為1000
"1000"
127.0.0.1:6379> DECRBY money 400 #取400,余額為600
(integer) 600
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

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

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