【redis】事務詳解,相關命令multi、exec、discard 與 watch 的原理

文章目錄

  • 什么是事務
    • 原子性
    • 一致性
    • 持久性
    • 隔離性
  • 優勢
    • 與 MySQL 對比
    • 用處
  • 事務相關命令
    • 開啟事務——MULTI
    • 執行事務——EXEC
    • 放棄當前事務——DISCARD
    • 監控某個 key——WATCH
      • 作用場景
      • 使用方法
      • 實現原理
  • 事務總結

什么是事務

MySQL 事務:

  • 原子性:把多個操作,打包成一個整體
  • 一致性:事務執行之前和之后,數據都不能離譜(變化前后能對上號)
  • 持久性:事務中做出的修改都會存硬盤
  • 隔離性:事務并發執行,涉及到的一些問題

原子性

相比于 MySQL 來說,Redis 的事務就是個弟弟:

  • 原子性:Redis 的事務,到底有沒有原子性?存在爭議
    • 最原本的含義是把多個操作打包到一起,要么都執行,要么都不執行
    • Redis 做到了上述的含義,但是 MySQL 這里的原子性走的更遠
      • MySQL 也是把多個操作打包到一起,要么全都執行成功,要么都不執行。如果事務中有操作執行失敗的,就要進行回滾,把中間已經執行的操作,全部回退
      • Redis 事務中的如干操作,要是有失敗的,無所謂。

Redis 把多個操作打包到一起執行,已經可以稱為是原子性了,只是 MySQL 標桿,提高了“原子性”門檻,這就使人們談到原子性的時候,更多的想到的是 MySQL 這樣帶回滾的原子性

所以,一般說到 Redis 的事務有沒有原子性,更多的傾向于沒有(或者弱化的原子性

一致性

Redis 沒有約束,也沒有回滾機制,事務執行過程中如果某個修改操作出現失敗,就可能引起不一致的情況

  • 所以 Redis 事務不具備一致性

持久性

reids 本身就是內存數據庫,數據是存儲在內存中的,雖然 Redis 也有持久化機制(AOF),但這里的持久化機制和事務沒有什么關系

  • MySQL 那邊,事務百分百有持久性,Redis 這邊把持久化機制關了。這是不一樣的
  • 所以 Redis 事務不具備持久性

隔離性

Redis 是一個單線程模型的服務器程序,所有的請求/事務都是“串行”執行的。而談到隔離性,都是并發執行才會涉及到的

  • 所以 Redis 事務不涉及隔離性

優勢

Redis 事務,主要的意義就是為了“打包”,避免其他客戶端的命令,插隊插到中間

  • Redis 中實現事務,是引入了一個隊列(每個客戶端都有一個)
  • 開啟事務的時候,此時客戶端輸入的命令,就會發給服務器,并且進入這個隊列中(而不是立即執行)。當遇到了“執行事務”命令的時候,此時就會把隊列中的這些任務都按順序依次執行
    • 按順序依次執行”是在 Redis 主線程中完成的,主線程會把事務中的操作都執行完,再處理別的客戶端

與 MySQL 對比

Redis 的事務為什么就設計的這么簡單,而不設計成和 MySQL 一樣強大呢?

  • MySQL 的事務,在背后付出了很大的代價
    • 空間上,要花費更多的空間來存儲更多的數據(實現回滾,就要額外開辟空間去存儲必要的日志…)
    • 時間上,也要有更大的執行開銷 (需要做更多額外的動作)

正是因為 MySQL 上述的問題,才有 Redis 上場的機會(簡單高效的優勢)

用處

什么時候需要用到 Redis 事務呢?

  • 如果我們需要把多個操作打包進行操作,使用事務是比較合適的

比如一個商品秒殺出售場景
一個貨品 A,進行秒殺出售,市場火爆。此時最重要的就是不能出現“超賣”的情況(超賣:放貨 5000 臺,賣出了 5001 臺)

一個典型的程序寫法:

獲取倉庫中剩余的商品個數
if(個數 > 0) {下單成功;個數--;
}
  • 如果不加上任何限制,就可能會存在"線程安全"問題
  • 所以我們得讓 下單成功個數-- 這兩個操作是原子的
    • 以前在多線程中,是通過加鎖的方式,來避免插隊
    • Redis 中,就直接使用事務即可

使用事務之后的寫法:

開啟事務
get count
if count > 0decr count
執行事務
  • redis 接收到命令的時候,不會立即執行,只會將其按順序放在隊列中。當收到“執行事務”操作的時候,才會開始按順序執行命令image.png
  • 第二個客戶端的“執行事務”命令發過來之后,服務器才真正執行第二個事務中的內容。此時第一個事務執行命令已經運行過了,此時第二個事務 get 到的 count 就已經是第一個事務自減之后的結果了

這個場景中,沒加鎖,也能解決上述“超賣”問題

redis 命令里能進行條件判定嗎?

  • redis 原生命令中確實沒有這種條件判斷定,但是 redis 支持 lua 腳本
    • lua 是另外一種編程語言,特點是小巧,很多程序都可以內嵌 lua 語言,從而去執行其他的語言
  • 通過 lua 腳本,就能實現上述的“條件判定”,并且也和事務一樣是打包批量執行的
  • lua 腳本的實現方式,是 redis 事務的進階版本

確實,redis 的事務的應用場景,沒有 MySQL 的事務那么多(有點雞肋的感覺)。redis 如果是按照集群模式部署,就不支持事務

事務相關命令

開啟事務——MULTI

(貓體,不是馬體)

開啟一個事務,執行成功返回 OK
image.png

  • 此時只是在服務器的事務隊列中,保存了上述請求,并沒有真正執行命令
  • 此時如果另外開一個客戶端,嘗試查詢這幾個 key,是查詢不到的

執行事務——EXEC

真正執行事務
image.png

  • 此時客戶端才會真正把上述操作發給客戶端,此時就可以獲取到 key 的值了image.png

放棄當前事務——DISCARD

放棄當前事務,此時直接清空事務隊列,之前的操作都不會真正執行到image.png|332
image.png|367

  • 前面輸入的命令,都被丟棄了

當我們開啟事務,并且給服務器發送若干命令之后,此時重啟服務器,會怎么樣?

  • 此時的效果就等同于 discard
  • 事務隊列終歸是內存中的結構,重啟之后,自然是沒有了

監控某個 key——WATCH

在執行事務的時候,如果某個事務中修改的值,被別的客戶端修改了,此時就容易出現數據不一致的問題

作用場景

image.png|525
從時間上來看,客戶端 1 是先發送了 set key 222,客戶端 2 是后發送了 set key 333

  • 由于客戶端 1 中,得是 exec 執行了,才會真正執行 set key 222。這個操作變成了實際上更晚執行的操作,最終 key 的值就是 222

使用方法

在剛才的場景中,就可以使用 watch 命令來監控這個 key,看看這個 key 在事務的 multiexec 之間,set key 之后,是否在外部被其他客戶端修改了image.png|405

  • 被監控的 key 被修改之后,exec 之后返回值為 nil

實現原理

watch 的實現,類似與一個“樂觀鎖

  • 樂觀鎖/悲觀鎖不是指某個具體的鎖,而是指的是某一類鎖的特征
  • 樂觀鎖:加鎖之前,就有一個心理預期,接下來鎖的沖突概率較低
  • 悲觀鎖:加鎖之前,也有一個心理預期,接下來鎖的沖突概率較高
    • 沖突:兩個線程針對同一個鎖加鎖,一個能加鎖成功,另一個就得阻塞等待
  • 鎖沖突概率高低,接下來要做的工作是不一樣的

樂觀鎖在 https://yeeear.blog.csdn.net/article/details/141102212 這篇文章中有詳細解釋

rediswatch 就相當于是基于版本號這樣的機制,來實現了“樂觀鎖”(就是 CAS 中的 ABA 問題的解決方法
image.png|608

  • watch 必須搭配事務使用,并且必須在 multi 之前使用
  • 如果 watch 的版本號和 exec 的版本號
    • 一致:說明當前 key 在事務開啟到最終執行這個過程中,沒有被別的客戶端修改,于是才能真正進行設置
    • 不一致:說明 key 在其他客戶端中改過了,因此此處就直接丟棄事務中的操作,exec 返回 nil

所以,watch 本質上就是給 exec 加了一個判定條件

事務總結

Redis 的事務,要比 MySQL 的事務,簡單很多

  1. 原子性:Redis 的事務,并不支持回滾
  2. 一致性:Redis 并不會保證事務執行前后的內容統一
  3. 持久性:Redis 主要通過內存來存儲數據
  4. 隔離性:Redis 自身作為一個單線程的服務器模型,上面處理的請求本質上都是串行執行的

四個關于事務的命令:

  1. 開啟事務—— nulti
  2. 執行事務—— exec
  3. 放棄當前事務—— discard
  4. 監控某個 key 是否被修改—— watch

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/74367.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/74367.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/74367.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【Java SE】單例設計模式

參考筆記:深入理解Java設計模式:單例模式及其餓漢式與懶漢式的對比,-CSDN博客 目錄 1.什么是設計模式 2.經典設計模式 3.單例設計模式(static屬性/方法經典使用場景 ) 3.1 餓漢式單例模式 3.2 懶漢式單例模式 4.補充 1.什么…

【day2】數據結構刷題 棧

一 有效的括號 給定一個只包括 (,),{,},[,] 的字符串 s ,判斷字符串是否有效。 有效字符串需滿足: 左括號必須用相同類型的右括號閉合。左括號必須以正確的順序閉合。每個右括號都有一個對應的…

藍橋杯 勁舞團

問題描述 小藍最近迷上了一款名為 “勁舞團” 的游戲。 在游戲中,只要按照給出的鍵位提示依次按出對應的鍵位,游戲人物便可以跟隨節奏跳舞。 對于連續的 K 次正確敲擊,如果任意連續兩次敲擊之間的時間間隔都小于等于 1 秒(即 1…

數據庫數值函數詳解

各類資料學習下載合集 ??https://pan.quark.cn/s/8c91ccb5a474?? 數值函數是數據庫中用于處理數值數據的函數,可以用于執行各種數學運算、統計計算等。數值函數在數據分析及處理時非常重要,能夠幫助我們進行數據的聚合、計算和轉換。在本篇博客中,我們將詳細介紹常用的…

關于金融開發領域的一些專業知識總結

目錄 1. 交易生命周期 1.1 證券交易所 1.1.1 交易前 1) 訂單生成(Order Generation) 2) 訂單管理(Order Management) 1.1.2 交易執行 3) 交易匹配(Trade Matching) 1.1.3 交易后 4) 交易確認&…

Leetcode 3495. Minimum Operations to Make Array Elements Zero

Leetcode 3495. Minimum Operations to Make Array Elements Zero 1. 解題思路2. 代碼實現 題目鏈接:3495. Minimum Operations to Make Array Elements Zero 1. 解題思路 這一題的話核心就是統計對任意自然數 n n n,從 1 1 1到 n n n當中所有的數字對…

Vue 3 + TypeScript 實現視頻播放與字幕功能:集成西瓜播放器 XGPlayer

文章目錄 1. 前言:視頻播放器的重要性2. 準備工作2.1 安裝 Vue 3 項目2.2 安裝 XGPlayer 和相關依賴 3. 實現視頻播放3.1 初始化 XGPlayer 4. 添加字幕功能4.1 配置字幕 4.2 字幕文件格式5. 增加交互性完整的代碼,僅供參考6. 總結 在現代 Web 開發中&…

MacOS安裝 nextcloud 的 Virtual File System

需求 在Mac上安裝next cloud實現類似 OneDrive 那樣,文件直接保存在服務器,需要再下載到本地。 方法 在 官網下載Download for desktop,注意要下對版本,千萬別下 Mac OS默認的那個。 安裝了登錄在配置過程中千萬不要設置任何同…

.NET 9 徹底改變了 API 文檔:從 Swashbuckle(Swagger) 到 Scalar

示例代碼下載:https://download.csdn.net/download/hefeng_aspnet/90404652 摘要 API 文檔是現代軟件開發的支柱。隨著 .NET 9 從 Swashbuckle 轉向 Microsoft.AspNetCore.OpenApi,開發人員需要新的策略來保持高效。本文探討了這些變化,并介…

深入剖析Java虛擬機(JVM):從零開始掌握Java核心引擎

📌 引言:為什么每個Java開發者都要懂JVM? 想象你是一名賽車手,Java是你的賽車,而JVM就是賽車的引擎。 雖然你可以不關心引擎內部構造就能開車,但要想在比賽中獲勝,必須了解引擎如何工作&#…

怎么連接linux服務器的桌面

一、使用 VNC(Virtual Network Computing) 1. 服務器端配置(Ubuntu 22.04 示例) # 安裝 VNC 服務器(以 TigerVNC 為例) sudo apt update sudo apt install tigervnc-standalone-server tigervnc-xorg-ext…

elasticsearch 通用筆記

文章目錄 一、前言二、內容說明1、目錄簡介2、本文例子前提內容 三、操作內容1、設置ES為服務2、查看健康度參數解析 3、索引相關查詢3.1、查詢指定索引內容3.1.1、匹配查詢3.1.2、精確匹配(不嘗試分詞)3.1.3、范圍查詢3.1.4、id查詢3.1.5、通配符及前綴…

windows安裝配置FFmpeg教程

1.先訪問官網:https://www.gyan.dev/ffmpeg/builds/ 2.選擇安裝包Windows builds from gyan.dev 3. 下滑找到release bulids部分,選擇ffmpeg-7.0.2-essentials_build.zip 4. 然后解壓將bin目錄添加path系統變量:\ffmpeg-7.0.2-essentials_bui…

強大的AI網站推薦(第二集)—— V0.dev

網站:V0.dev 號稱:前端開發神器,專為開發人員和設計師設計,能夠使用 AI 生成 React 代碼 博主評價:生成的UI效果太強大了,適合需要快速創建UI原型的設計師和開發者 推薦指數:🌟&…

c#知識點補充4

1.發布者訂閱模式 發布者 訂閱者 倆者直接的關聯使用

01、聊天與語言模型

一、簡單說明模型 LLM目前有兩種API提供 LanguageModel:接收一個a作為輸入并返回一個b作為輸出,這種是已經過時的ChatLanguageModel:接收多個輸入,然后返回相應的輸出 ChatLanguaggeModel是LangChain4j中LLM交互低級API&#x…

SQL的DCL,DDL,DML和DQL分別是什么

SQL(Structured Query Language)包括以下四種主要語言類別,分別用于不同的數據庫操作: 1. DCL(Data Control Language,數據控制語言) 用于控制數據庫訪問權限和安全。 常見命令: …

spring boot maven一欄引入本地包

1、在項目跟目錄下建立文件夾&#xff0c;比如libs 2、maven依賴 <dependency><groupId>com.hikvision.ga</groupId><artifactId>artemis-http-client</artifactId><version>1.1.10</version><scope>system</scope>&l…

連續型隨機變量及其分布

連續型隨機變量 數學公式可以看作一門精確描述事物的語言&#xff0c;比語言尤其是漢語的模糊性精確多了&#xff01;離散型數據的處理可以通過枚舉和相加進行處理。而連續型數據則沒有辦法這樣處理。我們必須要通過函數和取值區間還有微積分計算。 &#xff3b;定義1&#x…

AI重構SEO關鍵詞優化路徑

內容概要 人工智能技術的深度應用正在推動SEO優化進入全新階段。傳統關鍵詞優化依賴人工經驗與靜態規則&#xff0c;存在效率瓶頸與策略滯后性缺陷。AI技術通過智能語義分析系統&#xff0c;能夠穿透表層詞匯限制&#xff0c;精準捕捉用戶搜索意圖的語義關聯網絡&#xff0c;結…