使用Redis實現樂觀鎖

2022-05-10 23:45:18 字數 1606 閱讀 7851

事務是乙個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。

事務是乙個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。這點和mysql的事務不太一樣,在mysql事務開啟後,當操作中存在異常,則會導致事務回滾,不會出現資料異常,但是對於redis而言,當事務執行過程中,出現異常,redis會

記錄異常,但是操作會繼續執行。

redis事務是一組命令的集合。多組命令進入到等待執行的事務佇列中,執行exec命令告訴redis將等待執行的事務佇列中的所有命令,按順序執行,返回值就是這些命令組成的列表。

redis 事務可以一次執行多個命令, 具有下列保證:

乙個事務從開始到執行會經歷以下三個階段:

事務中的錯誤:

伺服器會對命令入隊失敗的情況進行記錄,並在客戶端呼叫 exec 命令時,拒絕執行並自動放棄這個事務

例如:

在 exec 命令執行之後所產生的錯誤, 並沒有對它們進行特別處理:即使事務中有某個/某些命令在執行時產生了錯誤, 事務中的其他命令仍然會繼續執行

例如:

redis 事務入隊只會檢查語法錯誤,對於exec後執行錯誤,沒有回滾措施。而且在事務中無法在客戶端做查詢判斷,只會得到queued,無法進行業務資料判斷,也是很坑。

redis的事務命令:

multi 開啟事務

exec 執行

discard 取消事務

watch key 監視key

unwatch key取消監視

樂觀的認為資料不會出現衝突,使用version或timestamp來記錄判斷。樂觀鎖的優點開銷小,不會出現鎖衝突。

可利用watch命令監聽key,實現樂觀鎖,來保證不會出現衝突,應用場景比如秒殺來防止超賣。

偽**如下:

實際**如下:

//商品總量

$shop_account = $request->input('number');

//商品總庫存的鍵

$products = 'products';

//判斷商品是否存在

if(!redis::exists($products))

//判斷商品是否還有庫存

if(redis::get($products) == 0)

//判斷購買的商品數量是否大於庫存數量

if(redis::get($products) < $shop_account)

//開始購買

try}catch (\exception $exception)

Redis實現樂觀鎖

悲觀鎖 樂觀鎖 127.0.0.1 6379 set money 100 ok127.0.0.1 6379 set out 0 ok127.0.0.1 6379 watch money 監事 money 物件 ok127.0.0.1 6379 multi 事務正常結束,資料期間沒有發生變動,這個時候...

redis實現樂觀鎖

redis測試監控 正常執行成功!127.0.0.1 6379 set money 100 ok127.0.0.1 6379 set out 0 ok127.0.0.1 6379 watch money 監視money物件 ok127.0.0.1 6379 multi ok127.0.0.1 637...

樂觀鎖的使用 redis

悲觀鎖 什麼時候都出問題,無論做什麼都加鎖 樂觀鎖 什麼時候都不會出現問題,所以不會上鎖,更新資料的時候進行判斷,在此期間是否有人對資料進行了改變 獲取version,更新的時候比較version,監控 watch。事務正常結束,資料期間沒有發生改變,這個時候就正常執行成功,監視失敗,要放棄監視un...