Redis樂觀鎖在電影購票業務中的應用
hello你好我是辰兮很高興你能來閱讀,本篇繼續之前文章電影購票系統的設計,講解Redis事務和樂觀鎖等相關知識點,分享獲取新知大家一起進步!
一、Redis序言
Redis鍵值對設計:Redis在電影票系統的設計與實現
繼續整理電影購票的專案中涉及到Redis事務和Redis的樂觀鎖的相關概念,現整理一下相關知識,來更加深入瞭解
在高併發的專案中,常常要用一些方法來保障資料的準確性,通過這種手段保證了當前使用者和其他使用者一起操作的時候,所得到的結果和他單獨操作是一樣的,這就是我們常說的併發控制。簡單的說就是你不影響別人,別人操作也不影響你。
用電影購票業務解釋,如果此時你購買了電影票但是你未支付,此時有一個十五分鐘的支付時間,這個座位就是被佔的,其他使用者是無法購買你這個座位的。
如果購買成功了會怎麼樣?
那就會出現兩張一樣的票在同一個座位,這不算是交通事故嘛哈哈
二、Redis事務
回顧一下Redis事務?
1、Redis中的事務(transaction)是一組命令的集合。
2、事務同命令一樣都是Redis最小的執行單位,一個事務中的命令要麼都執行,要麼都不執行。
3、Redis事務的實現需要用到 MULTI 和 EXEC 兩個命令,事務開始的時候先向Redis伺服器傳送 MULTI 命令,然後依次傳送需要在本次事務中處理的命令,最後再傳送 EXEC 命令表示事務命令結束。
Redis的事務是下面4個命令來實現
Redis的事務是下面4個命令來實現
1.multi,開啟Redis的事務,置客戶端為事務態。
2.exec,提交事務,執行從multi到此命令前的命令佇列,置客戶端為非事務態。
3.discard,取消事務,置客戶端為非事務態。
4.watch,監視鍵值對,作用時如果事務提交exec時發現監視的監視對發生變化,事務將被取消。
三、Redis樂觀鎖
無論是悲觀鎖還是樂觀鎖,都是我們定義的一個概念
樂觀鎖:redis大多數是基於資料版本(version)的記錄機制實現的。即為資料增加一個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表新增一個version欄位來實現。在讀取資料時,將此版本號一同讀出,之後更新時對此版本號加1。此時,將提交資料的版本號與資料庫表對應記錄的當前版本號進行對比,如果提交的資料版本號大於資料庫當前版本號,則予以更新,否則認為是過期資料。
Redis中對樂觀鎖的實現: 假設有一個age的key,我們開啟兩個session來對age進行賦值操作。
session1:
127.0.0.1:6379> get age
"10"
127.0.0.1:6379> watch age #開啟對age鍵的監控(監控其他操作是否對age鍵有修改操作)
OK
127.0.0.1:6379> multi #開啟事務上下文
OK
session2:
127.0.0.1:6379> set age 20
OK
127.0.0.1:6379> get age
"20"
再看session1:
127.0.0.1:6379> set age 30 #在session2中操作age後,我們在session1中繼續操作age
127.0.0.1:6379> exec #執行事務 返回nil 事務執行不成功。
(nil)
127.0.0.1:6379> get age
"20"
在這裡我們發現事務不能執行成功,這就是因為session1中的資料版本已經小於資料庫中的資料版本。這就是Redis的樂觀鎖。
Redis的樂觀鎖設定
當我們點選購票後我們的redis的座位會被鎖定,這樣的好處,避免兩個人購買相同的座位。每一次購票到完成就相當於一次Redis的事務,我們可以思考這次購票要麼成功,要麼失敗,不然就會導致兩個人購買同一張票的情況。具體的操作如下,即確保了不能重複購買電影票。使用者在選座的時候執行multi這個方法。
其實簡單的來說就是當我已經預定座位(未支付)此時我都會對這個座位進行相關的監聽watch,其它的人無法再對我的座位進行購買預定等相關操作,直到我提交事務exec。
這樣座位就不會賣給兩個人了。
測試環節如何測試上述Redis樂觀鎖的成功?
你先購買幾張電影票,到付款介面,不支付,然後退出去,再進來選座頁面,你可以看到剛剛選座的座位邊紅色了,這是因為座位的顯示也是從Redis中封裝出來的,具體詳情業務請參考我上一篇文章。
業務邏輯補充講解
這裡是我們點選購票後所進入的頁面,我們可以對比上述的購票座位,檢查發現是一致的,我們購票後通過redis鎖定座位,和電影院的業務邏輯一樣,我們設計了十五分鐘的過期時間,即如果你十五分鐘內未進行支付,則會出現訂單支付失敗,請重新購票。
這裡前端和後臺都要做定時器,Redis選座超過十五分鐘要把這個座位釋放掉,前端要提示使用者在規定時間內完成支付。
這樣的好處是為了防止惡意佔座的情況。
悲觀鎖解釋
悲觀鎖是基於一種悲觀的態度類來防止一切資料衝突,它是以一種預防的姿態在修改資料之前把資料鎖住,然後再對資料進行讀寫,在它釋放鎖之前任何人都不能對其資料進行操作,直到前面一個人把鎖釋放後下一個人資料加鎖才可對資料進行加鎖,然後才可以對資料進行操作,一般資料庫本身鎖的機制都是基於悲觀鎖的機制實現的;
樂觀鎖比較適用於讀多寫少的情況(多讀場景),悲觀鎖比較適用於寫多讀少的情況(多寫場景)。
The best investment is to invest in yourself.
2020.11.15 晚21:51 願你們奔赴在自己的熱愛里!
相關文章
- 樂觀鎖和悲觀鎖在kubernetes中的應用
- Redis的事務、樂觀鎖和悲觀鎖Redis
- 關於樂觀鎖與悲觀鎖的實際應用
- Java中的鎖之樂觀鎖與悲觀鎖Java
- 深入理解Redis事務、事務異常、樂觀鎖、管道Redis
- Java中的樂觀鎖——無鎖策略Java
- 面試官:你說說互斥鎖、自旋鎖、讀寫鎖、悲觀鎖、樂觀鎖的應用場景面試
- 業務上鎖的應用
- Disruptor在雲音樂特徵服務中的應用特徵
- 利用MySQL中的樂觀鎖和悲觀鎖實現分散式鎖MySql分散式
- 悲觀鎖和樂觀鎖
- redis在nodejs中的應用RedisNodeJS
- redis在python中的應用RedisPython
- msyql樂觀鎖和悲觀鎖
- 理解樂觀鎖和悲觀鎖
- MybatisPlus - [03] 樂觀鎖&悲觀鎖MyBatis
- laravel樂觀鎖和悲觀鎖Laravel
- MySQL鎖(樂觀鎖、悲觀鎖、多粒度鎖)MySql
- Spring事件,ApplicationEvent在業務中的應用Spring事件APP
- SpringPlugin-Core在業務中的應用SpringPlugin
- Lua 指令碼在 Redis 事務中的應用實踐指令碼Redis
- Lua指令碼在Redis事務中的應用實踐指令碼Redis
- JPA和Hibernate的樂觀鎖與悲觀鎖
- MySQL 悲觀鎖與樂觀鎖的詳解MySql
- MySQL/InnoDB中,樂觀鎖、悲觀鎖、共享鎖、排它鎖、行鎖、表鎖、死鎖概念的理解MySql
- Java開發技巧——併發控制中的樂觀鎖與悲觀鎖Java
- 樂觀鎖心得
- hibernate 樂觀鎖
- MySQL 樂觀鎖MySql
- 樂觀鎖CAS
- java-樂觀鎖與悲觀鎖Java
- 小白科普:悲觀鎖和樂觀鎖
- 淺析樂觀鎖與悲觀鎖
- 深度分析Redis分散式鎖在電商超賣業務場景下的使用Redis分散式
- 策略模式在實際業務中的應用模式
- 策略模式在業務中的實際應用模式
- Redis在遊戲業務中的使用Redis遊戲
- MySQL樂觀鎖和悲觀鎖介紹MySql