Redis事務的理解與使用

文章目錄

  • Redis 事務
    • 1)基本認識
    • 2)事務操作
      • 1.MULTI
      • 2.EXEC
      • 3.錯誤處理
      • 4.DISCARD
      • 5.WATCH
      • 6.SCRIPT

Redis 事務

官方文檔,永遠是你學習的第一手資料:Redis 事務

1)基本認識

?談到事務,大家首先都會聯想到 mysql 中復雜但又功能強大的“事務”,和 mysql 相比,redis 所提供的事務簡直就是個“弟弟”。我們從 mysql 事務的四大基本特點進行比較:

原子性:

?原子性最初的含義就是把多個操作打包到一起,要么全部執行,要么全部不執行。但是mysql 在原子性這條道路上走的更遠,它要求多個操作要么全部執行成功,要么全部不執行,如果其中任一操作執行失敗,都會 rollback 確保數據的一致性。

?Redis 事務可以說具有原子性,也可以說沒有,這是一個理解角度的問題。Redis 事務確實可以將多個操作打包一起執行,從這方面談,Redis 是具有原子性的;但是和 mysql 不同,Redis 事務并不保證所有命令執行成功,由于 mysql 的標桿作用“拉高”了原子性的標準,從這一方面說,Redis 并不具有原子性。

?早些版本的 Redis 官網中明確提出了, Redis 事務具有原子性,但現在去看,官網已經把第一句刪掉了。看連 Redis 官方都 “慫了”,所以我們還是傾向于認為 Redis 不具有原子性

image-20231121200726156

?那為什么 Redis 不提供和 mysql 一樣強大的事務機制呢?首先 mysql 為了實現事務機制付出了巨大的代價,而 Redis 則是主打一個輕量簡單,如果和 mysql 一樣就丟了自己的特色,那又怎么從這么多數據庫中沖殺出來呢?

一致性:

?由于 Redis 并不提供事務回滾機制,當其中某些操作失敗時就會造成數據不一致的問題。例如以下這個場景:張三給李四轉賬 1000 元。張三余額 -1000 的操作成功,但是李四余額 + 1000 的操作失敗,而 redis 并不會因為操作執行失敗而回滾數據,從而導致數據不一致的問題發生

持久性:

?mysql 中又 redo log 保證事務的持久性,但是 redis 事務本身并不具有持久性,持久化還得依賴redis的 rdb 或者 aof 機制。但是否開啟持久化,是redis-server自己的決定,和事務本身無關

隔離性:

?Redis 沒有也不需要隔離性。隔離性是針對并發讀寫的問題而引入了,而 Redis 是一個單進程的數據庫,不存在這方面的煩惱。

2)事務操作

1.MULTI

  • multi 指令用于開啟一個事務

    127.0.0.1:6379> multi
    OK
    
  • Redis 服務端為每一個客戶端維護一個事務命令隊列,multi 后所有命令(除了 exec)都會被添加到隊列中而不是立即執行(queued 狀態)

    127.0.0.1:6379> set key1 1
    QUEUED
    127.0.0.1:6379> set key1 2
    QUEUED
    

2.EXEC

  • exec 指令用于按次序一次性執行事務隊列中命令

    127.0.0.1:6379> exec
    1) OK
    2) OK
    127.0.0.1:6379> get key1
    "1"
    

3.錯誤處理

在 Redis 事務中存在兩種類型的錯誤:

  • 在調用 exec 前發生錯誤,例如某個指令中存在語法錯誤。當這種錯誤發生時,整個事務都會被直接丟棄

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> get key1
    QUEUED
    127.0.0.1:6379> abc
    (error) ERR unknown command `abc`, with args beginning with: 
    127.0.0.1:6379> exec
    (error) EXECABORT Transaction discarded because of previous errors.
    
  • 在調用 exec 期間發生的錯誤。在這種情況下,Redis 會繼續執行剩余的命令,不管某些命令是否失敗。

    127.0.0.1:6379> FLUSHALL
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> set key1 1
    QUEUED
    127.0.0.1:6379> LPOP key1
    QUEUED
    127.0.0.1:6379> set key2 2
    QUEUED
    127.0.0.1:6379> get key2
    QUEUED
    127.0.0.1:6379> EXEC
    1) OK
    2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
    3) OK
    4) "2"
    

    上面的案例也驗證了 Redis 事務只能保證多條一起執行,但并不保證所有的命令都會執行成功。失敗了也不會數據回滾,因而存在一致性的問題

4.DISCARD

  • discard 指令用于終止取消當前正在執行的事務,隊列中的所有指令都會被直接丟棄

    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> get key1
    QUEUED
    127.0.0.1:6379> get key2
    QUEUED
    127.0.0.1:6379> discard
    OK
    127.0.0.1:6379> exec
    (error) ERR EXEC without MULTI
    
  • 當前沒有正在執行的事務,則 discard 指令無效

    127.0.0.1:6379> discard
    (error) ERR DISCARD without MULTI
    

5.WATCH

用法:

  • 在執行事務期間,某個鍵值被其他客戶端修改了,其結果就容易令人產生歧義,例如下面這個場景

    timeclient_1client_2
    t1execute command multi
    t2execute command set key1 1
    ……
    t3execute command set key1 2
    t4execute command exec
  • watch 與事務配合使用,它允許你監視多個 key,如果在事務的執行期間任何一個鍵被其他客戶端修改,都會導致當前事務全部丟棄,從而確保了事務執行期間數據的一致性。watch 的作用時間從 multi 開始到執行 exec 結束。

    // client1
    127.0.0.1:6379> mset key1 1 key2 2
    OK
    127.0.0.1:6379> watch key1 key2
    OK
    127.0.0.1:6379> multi
    OK
    127.0.0.1:6379> mget key1 key2
    QUEUED
    127.0.0.1:6379> exec 
    (nil)    // 事務執行失敗// client2:在client1事務執行期間進行如下修改
    127.0.0.1:6379> incr key1
    (integer) 2
    127.0.0.1:6379> decr key2
    (integer) 1
    
  • unwatch 的作用與 watch 相反,它用于清除對所有 key 的 “watch”。在執行 exec 或者 client 退出時,所有的 key 都會 “unwatched”

原理:

?watch 本質就是一把樂觀鎖,通過CAS機制實現:每個 "watched " 變量都有一個初始版本號,修改變量會讓其版本號變大,在執行 exec 時會比較當前版本號與 watch 時的版本號是否一致,如果不一致,說明變量在事務執行期間發生了修改,當前事務就會被 discard

案例:

下面是官方文檔提供的一個使用案例,通過 watch 去創造一個新的原子操作:

WATCH zset
element = ZRANGE zset 0 0
MULTI
ZREM zset element
EXEC

?從 zset 中刪除一個元素有兩部:1)找到最小的元素 2) 將最小的元素刪除。如果刪除失敗,說明最小值被其他客戶端修改,那么我們就重復上面操作,直到刪除一個最小值

6.SCRIPT

?任何 redis 事務能完成的操作,我們都可以使用 redis script 完成。redis script 天生就有把多個指令打包執行的能力,感興趣的可以去網上找找 lua 腳本操作 redis 的教程

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

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

相關文章

MySQL面試題總結

1. 表之間如何關聯 表與表之間常用的關聯方式有兩種:內連接、外連接,下面以MySQL為例來說明這兩種連接方式 內連接通過INNER JOIN來實現,它將返回兩張表中滿足連接條件的數據,不滿足條件的數據不會查詢出來 外連接 外連接通過OUTE…

SpringBoot——感謝尚硅谷官方文檔

SpringBoot——感謝尚硅谷官方文檔 1 Spring與SpringBoot1、Spring能做什么1.1、Spring的能力1.2、Spring的生態1.3、Spring5重大升級1.3.1、響應式編程1.3.2、內部源碼設計 2、為什么用SpringBoot2.1、SpringBoot優點2.2、SpringBoot缺點 3、時代背景3.1、微服務3.2、分布式分…

Dubbo從入門到上天系列第十八篇:Dubbo引入Zookeeper等注冊中心簡介以及DubboAdmin簡要介紹,為后續詳解Dubbo各種注冊中心做鋪墊!

文章目錄 一:Dubbo注冊中心引言 1:什么是Dubbo的注冊中心? 2:注冊中心關系圖解 3:引入注冊中心服務執行流程 4:Dubbo注冊中心好處 5:注冊中心核心作用 二:注冊中心實現方案 …

10.docker的網絡network-概述

1.docker的網絡模式 docker共有四種網路模式,分別是bridge、host、none和container. 1.1 bridge bridge,也稱為虛擬網橋。在bridge模式下,為每個容器分配、配置IP等,并將容器連接到一個docker0。使用–network bridge命令指定,…

【01】ES6:ECMAScript 介紹

ECMAScript 6.0 (以下簡稱 ES6)是 JavaScript 語言的下一代標準,已經在 2015 年 6 月正式發布。它的目標,是使得 JavaScript 語言可以用來編寫復雜的大型應用程序,成為企業級開發語言。 參考:《ECMAScript…

C# Winform使用log4net記錄日志

寫在前面 Log4Net是從Java的log4j移植過來的,功能也與log4j類似,可以把日志信息輸出到文件、數據庫、控制臺、Windows 事件日志、遠程系統日志服務等不同的介質或目標。 Log4Net配置選項豐富靈活,并且可在運行時動態更新配置并應用&#xf…

解析紫光展銳T820 5G芯片——讓照片接近原色

紫光展銳系統級安全的高性能5G SoC芯片平臺T820,采用八核CPU架構,6nm EUV先進工藝,金融級全內置安全方案,在性能、功耗與5G通信體驗等方面,較上一代產品更為出色。 此前,已經為大家講解過T820的拍照、安全性…

mac跑分工具 Geekbench v6.2.2

Geekbench 6 是一款跨平臺的系統性能測試軟件,可以對處理器和內存等硬件進行評測,并提供了單核和多核兩種測試模式。該軟件適用于 Windows、macOS、Linux 和 iOS 等多種操作系統平臺。 Geekbench 6 測試可以幫助用戶快速準確地了解自己設備的性能表現&am…

【brpc學習實踐五】brpc自適應限流案例

自適應限流 服務的處理能力是有客觀上限的。當請求速度超過服務的處理速度時,服務就會過載。 如果服務持續過載,會導致越來越多的請求積壓,最終所有的請求都必須等待較長時間才能被處理,從而使整個服務處于癱瘓狀態。 與之相對…

PHP中間件實現

目錄 1、簡單中間實現 2、使用閉包函數實現中間件 在PHP中,中間件是一種常用的設計模式,用于處理請求和響應,它可以在請求到達目標處理程序之前或響應發送給客戶端之前執行一些特定的邏輯。中間件提供了一種靈活的方式來修改或擴展應用程序的…

查看當前laravel版本三種方法(筆記二)

1、在終端中使用 Artisan 命令:在 Laravel 項目的根目錄下,打開終端(命令行界面),然后運行以下命令: php artisan --version 2、控制器中打印版本 var_dump(app()->version()); 3、在 Laravel 項目的根目…

【kubernetes】k8s架構之節點

文章目錄 1、集群架構示意圖2、概述3、管理3.1 節點名稱唯一性3.2 節點自注冊3.3 手動節點管理 4、節點狀態4.1 地址(Addresses)4.2 狀況(Condition)4.3 容量(Capacity)與可分配(Allocatable&am…

PTA-輸出三角形面積和周長

本題要求編寫程序,根據輸入的三角形的三條邊a、b、c,計算并輸出面積和周長。注意:在一個三角形中, 任意兩邊之和大于第三邊。三角形面積計算公式:areas(s?a)(s?b)(s?c)?,其中s(abc)/2。 輸入格式&…

某60區塊鏈安全之Call函數簇濫用實戰二學習記錄

區塊鏈安全 文章目錄 區塊鏈安全Call函數簇濫用實戰二實驗目的實驗環境實驗原理實驗內容實驗步驟EXP利用 Call函數簇濫用實戰二 實驗目的 學會使用python3的web3模塊 學會并區分以太坊call、staticcall、delegatecall三種函數調用的特點 找到合約漏洞進行分析并形成利用 實驗…

關于git hooks

Git hooks 是一種在 Git 倉庫中觸發自定義腳本的機制。這些腳本可以在特定的 Git 操作(如提交、推送、合并等)發生時執行。通過使用 Git hooks,你可以在版本控制的不同階段自動運行腳本,以執行一些定制化的操作。 在 Git 中&…

03梯度下降

目錄 lambda基礎知識 代碼 核心算法: lambda基礎知識 lambda 是 Python 中的一個關鍵字,用于創建匿名函數。匿名函數是一種沒有具體名稱的小型、臨時的函數,通常用于一次性的、簡單的操作。lambda 函數的語法如下:python Copy c…

高效運維工具,助力運維服務商為企業用戶提供IT遠程維保服務

一、背景介紹 隨著科技的迅速發展和信息化建設的不斷推進,IT運維在中小企業中的地位逐漸提升。IT運維是指通過技術手段和工具,對企業的IT基礎設施進行監控、管理和維護,以確保企業信息系統的穩定運行和業務的持續發展。 然而,對于…

計算3個點的6種分布在平面上的占比

假設平面的尺寸是6*6,用11的方式構造2,在用21的方式構造3 2 2 2 1 2 2 2 2 2 1 2 2 2 2 2 1 2 2 3 3 3 x 3 3 2 2 2 1 2 2 2 2 2 1 2 2 在平面上有一個點x,11的操作吧平面分成了3部分2a1,2a…

海康Visionmaster-模塊索引:MFC 模塊索引異常解決 辦法

現象:文件編碼格式為 UTF-8 不帶簽名編碼格式,模塊索引會出現 模塊無法找到異常 更改文件類型為 UTF-8 帶簽名格式或 vs 默認 GBK2312 編碼格式

JMeter處理接口簽名sign

寫接口腳本的時候,很多接口涉及到簽名,今天介紹下用JMeter編寫簽名腳本的方法。 舉個例子,開啟紅包接口,請求方式為post POST /v1/api/red/open json請求參數 { "red_id":1, "timestamp":"1667033841…