Redis事務、事務鎖

事務

一旦成功所有的成功,一個失敗,所有一些列連續動作都失敗

事務的基本操作

  • 開啓事務

multi

  • 作用
    設定事務的開啓位置,此指令執行後,後續的所有指令均加入到事務中
  • 執行事務

exec

  • 作用
    設定事務的結束位置,同時執行事務。與multi成對出現,成對使用

 

å¨è¿éæå¥å¾çæè¿°

注意:加入事務的命令暫時到任務隊列中,並沒有立即執行,只有執行exec命令纔開始執行

事務定義過程中發現問題,怎麼辦?

  • 取消事務

discard

  • 作用
    終止當前事務定義,發生在multi之後,exec之前

事務的工作流程

在這裏插入圖片描述

 事務的注意事項

  • 語法錯誤
    指命令書寫格式有誤

  • 處理結果
    如果定義的事務中所包含的命令存在語法錯誤,整體事務中所有命令均不會被執行。包括那些語法正確的命令

  • 運行錯誤
    指命令格式正確,但是無法正常的執行。例如對list進行incr操作

  • 處理結果
    能夠正確運行的命令會執行,運行錯誤的命令不會執行
    注意:已經執行完畢的命令對應的數據不會自動回滾,需要程序員自己在代碼中實現回滾。

手動進行事務回滾

  • 記錄操作過程中被影響的數據之前的狀態
    單數據:string
    多數據:hash,list,set,zset
  • 設置指令恢復所有的被修改的項
    單數據:直接set(注意周邊屬性,例如時效)
    多數據:修改對應值或整體克隆複製

事務鎖

業務場景1
在這裏插入圖片描述

業務分析

  • 多個客戶端有可能同時操作一組數據,並且該數據一旦被操作修改後,將不適用於繼續操作
  • 在操作之前鎖定要操作的數據,一旦發生變化,終止當前操作

基於特定條件的事務執行——鎖

解決方案

  • 對key添加監視鎖,在執行exec前如果key發生了變化,終止事務執行(不管事務操作的是監控的key還是別的key都是不能執行的)

watch key1 [key2…]     

  • 取消對所有key的監視

unwatch

非常規的一種情況

業務場景2
天貓雙11熱賣過程中,對已經售罄的獲取追加補貨,且補貨完成。客戶購買熱情高漲,3秒內將所有商品購買完畢。本次補貨已經將庫存全部清空,如何避免最後一件商品不被多人同時購買?【超賣問題】

業務分析

  • 使用watch監控一個key有沒有改變已經不能解決問題,此處要監控的是具體數據
  • 雖然redis是單線程的,但是多個客戶端對同一個數據同時進行操作時,如何避免不被同時修改?

基於特定條件的事務執行——分佈式鎖

解決方案

  • 使用setnx設置一個公共鎖

setnx lock-key value

 利用setnx命令的返回值特徵,有值則返回設置失敗,無值則返回設置成功

  • 對於返回設置成功的,擁有控制權,進行下一步的具體業務操作
  • 對於返回設置失敗的,不具有控制權,排隊或等待
    操作完畢通過del操作釋放鎖

dek lock-key

 注意:上述解決方案是一種設計概念,依賴規範保障,具有風險性

業務場景
依賴分佈式鎖的機制,某個用戶操作時對應客戶機宕機,並且此時已經獲取到鎖,如何解決?
業務分析

  • 由於鎖操作由用戶控制加鎖,必定會存在加鎖後未解鎖的風險
  • 需要解鎖操作不能僅依賴用戶控制,系統級別要給出對應的保底處理方案

解決方案

  • 使用expire爲鎖key添加時間限定,到時不釋放,放棄鎖

expire lock-key second
pexpire lock-kay millisenconds

由於操作通常都是微秒或者毫秒級,因此該鎖設定時間不宜設置過大。具體時間需要業務測試後確認

  • 例如:持有鎖的操作最長執行時間127ms,最短執行時間7ms
  • 測試百萬次最長執行時間對應命令的最大消耗時,測試百萬次網絡延遲平均耗時
  • 鎖時間設定推薦:最大耗時* 120%+平均網絡延遲*110%
  • 如果業務最大耗時<<網絡平均延遲,通常爲2個數量級,取其中單個耗時較長即可

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章