Redis樂觀鎖在電影購票業務中的應用

辰兮要努力發表於2020-11-15

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 願你們奔赴在自己的熱愛里!

相關文章