十、Redis事務、事務鎖
事務簡介
什麼是事務:
Redis執行指令過程中,多條連續執行的指令被干擾、打斷、插隊。
redis單條命令式儲存原子性的,但是事務不保證原子性。
redis事務本質:一組命令的集合(佇列形式)。一個事務中的所有命令都會被序列化,在事務執行過程中,會按照順序執行。
redis事務就是一個命令執行的佇列,將一系列預定義命令包裝成一個整體(一佇列)。當執行時,一次性按照新增順序依次執行,中間不會被打斷或者干擾。
一旦成功所有的成功,一個失敗,所有一些列連續動作都失敗。
事務的基本操作
- 開啟事務
multi
- 作用
設定事務的開啟位置,此指令執行後,後續的所有指令均加入到事務中 - 執行事務
exec
- 作用
設定事務的結束位置,同時執行事務。與multi成對出現,成對使用
注意:加入事務的命令暫時到任務佇列中,並沒有立即執行,只有執行exec命令才開始執行
事務定義過程中發現問題,怎麼辦?
- 取消事務
discard
- 作用
終止當前事務定義,發生在multi之後,exec之前
事務的工作流程
事務的注意事項
- 語法錯誤
指命令書寫格式有誤,如果命令中有語法錯誤,將所有的命令跟事務指令都不執行。
- 處理結果
如果定義的事務中所包含的命令存在語法錯誤,整體事務中所有命令均不會被執行。包括那些語法正確的命令 - 執行錯誤
指命令格式正確,但是無法正常的執行。例如對list進行incr操作
- 處理結果
能夠正確執行的命令會執行,執行錯誤的命令不會執行
注意:已經執行完畢的命令對應的資料不會自動回滾,需要程式設計師自己在程式碼中實現回滾。
手動進行事務回滾
-
記錄操作過程中被影響的資料之前的狀態
單資料:string
多資料:hash,list,set,zset -
設定指令恢復所有的被修改的項
單資料:直接set(注意周邊屬性,例如時效)
多資料:修改對應值或整體克隆複製
事務-鎖
- 悲觀鎖,認為什麼時候都會出問題,無論做什麼都會加鎖
- 樂觀鎖,認為什麼時候都不會出問題,所以不會上鎖,更新資料的時候去判斷一下,在此期間是否有人修改過這個資料,使用watch去監視
業務場景1
業務分析
- 多個客戶端有可能同時操作一組資料,並且該資料一旦被操作修改後,將不適用於繼續操作
- 在操作之前鎖定要操作的資料,一旦發生變化,終止當前操作
基於特定條件的事務執行——鎖
解決方案
- watch監控必須在multi開啟事務之前執行,否則報錯。對key新增監視鎖,在執行exec前如果key發生了變化,將終止所有的事務執行
watch key1 [key2…]
- 取消對所有key的監視
unwatch
業務場景2
天貓雙11熱賣過程中,對已經售罄的獲取追加補貨,且補貨完成。客戶購買熱情高漲,3秒內將所有商品購買完畢。本次補貨已經將庫存全部清空,如何避免最後一件商品不被多人同時購買?【超賣問題】
業務分析
- 使用watch監控一個key有沒有改變已經不能解決問題,此處要監控的是具體資料
- 雖然redis是單執行緒的,但是多個客戶端對同一個資料同時進行操作時,如何避免不被同時修改?
基於特定條件的事務執行——分散式鎖
解決方案
- 使用setnx設定一個公共鎖
setnx lock-key value --setnx lock-num【key鍵】 1【value隨便給】
利用setnx命令的返回值特徵,有值則返回設定失敗,無值則返回設定成功
- 對於返回設定成功的,擁有控制權,進行下一步的具體業務操作
- 對於返回設定失敗的,不具有控制權,排隊或等待 操作完畢通過del操作釋放鎖
dek lock-key —刪除鎖
業務場景
依賴分散式鎖的機制,某個使用者操作時對應客戶機當機,並且此時已經獲取到鎖,如何解決?
業務分析
- 由於鎖操作由使用者控制加鎖,必定會存在加鎖後未解鎖的風險
- 需要解鎖操作不能僅依賴使用者控制,系統級別要給出對應的保底處理方案 解決方案
- 使用expire為鎖key新增時間限定,到時不釋放,放棄鎖
expire lock-key second --expire lock-key【鎖的key名】 second【時間,秒單位】
pexpire lock-kay millisenconds
由於操作通常都是微秒或者毫秒級,因此該鎖設定時間不宜設定過大。具體時間需要業務測試後確認
- 例如:持有鎖的操作最長執行時間127ms,最短執行時間7ms
- 測試百萬次最長執行時間對應命令的最大消耗時,測試百萬次網路延遲平均耗時
- 鎖時間設定推薦:最大耗時* 120%+平均網路延遲*110%
- 如果業務最大耗時<<網路平均延遲,通常為2個數量級,取其中單個耗時較長即可
相關文章
- redis-19.事務-鎖Redis
- 深入理解Redis事務、事務異常、樂觀鎖、管道Redis
- redis(10)事務和鎖機制Redis
- Redis 事務Redis
- redis事務Redis
- Redis的事務、樂觀鎖和悲觀鎖Redis
- Redis事務操作Redis
- redis-事務Redis
- Redis的事務Redis
- MySQL 事務和鎖MySql
- MySQL事務與鎖MySql
- MySQL事務和鎖MySql
- MyRocks事務鎖分析
- 【Redis 系列】redis 學習六,redis 事務處理和監控事務Redis
- Redis--事務理解Redis
- Redis 中的事務Redis
- NoSql-Redis事務SQLRedis
- InnoDB 事務加鎖分析
- MySQL 筆記 - 事務&鎖MySql筆記
- mysql之鎖與事務MySql
- MySQL詳解--鎖,事務MySql
- mysql事務和鎖InnoDBMySql
- sqlite的事務和鎖SQLite
- Oracle的事務和鎖Oracle
- 不支援原子性的 Redis 事務也叫事務嗎?Redis
- 雞肋的Redis事務Redis
- redis的事務處理Redis
- MySQL入門--事務與鎖MySql
- mysql鎖與事務總結MySql
- Oracle的TX鎖(行級鎖、事務鎖)Oracle
- node.js 中使用redis實現分散式事務鎖Node.jsRedis分散式
- 一文講透 Redis 事務 (事務模式 VS Lua 指令碼)Redis模式指令碼
- 一文了解:Redis事務Redis
- 誰說Redis不支援事務?Redis
- Redis 事務支援 ACID 麼?Redis
- Redis系列(九):Redis的事務機制Redis
- Redis系列12:Redis 的事務機制Redis
- 事務隔離(二):基於加鎖方式的事務隔離原理