Redis學習筆記(二十一) 事務

来源:https://www.cnblogs.com/xtt321/archive/2020/06/13/13122183.html
-Advertisement-
Play Games

文章開始啰嗦兩句,寫到這裡共21篇關於redis的瑣碎知識,沒有過多的寫編程過程中redis的應用,著重寫的是redis命令、客戶端、伺服器以及生產環境搭建用到的主從、哨兵、集群實現原理,如果你真的能看的進去,相信對你在以後用到redis時會有一定的幫助。 寫到現在,redis相關的內容暫時告一段落 ...


文章開始啰嗦兩句,寫到這裡共21篇關於redis的瑣碎知識,沒有過多的寫編程過程中redis的應用,著重寫的是redis命令、客戶端、伺服器以及生產環境搭建用到的主從、哨兵、集群實現原理,如果你真的能看的進去,相信對你在以後用到redis時會有一定的幫助。

寫到現在,redis相關的內容暫時告一段落了,以後可能更著重的去介紹c#相關的知識,包括用到IL、.net core底層、微服務等知識。

哎呀,寫著寫著突然又想啰嗦幾句,最近幾年c#在國內式微java如日中天,好多微軟系的小伙伴或者各路大神都不看好c#,網上相關的帖子更是多如牛毛,另外一個現象就是從職位到薪資被java、go等語言甩了n條街。

但我覺得拋開這些外界因素,單從技術或者說是語言上講c#其實非常優秀,雖然近幾年.net  core 有些不倫不類、各種借鑒(抄襲)其他語言的語法糖、各個大版本之間不相容等問題一堆,但是這並不影響他的優秀,畢竟成長確實要走很多彎路,所以希望有興趣繼續搞搞.net 的童鞋可以持續關註c#。


 

Redis通過MULTI、EXEC、WATCH等命令來實現事務,事務提供了一種將多個命令請求打包,然後一次性、按順序地執行多個命令的機制,並且在事務執行期間,伺服器不會中斷事務而改去執行其他客戶端命令請求,他會將事務中的所有命令執行完畢,然後採取處理其他客戶端的命令請求。

一個事務從開始到結束通常會經歷以下三個階段:事務開始、命令入隊、事務執行。

1)事務開始

MULTI命令的執行標誌是事務的開始,MULTI命令可以將執行該命令的客戶端的從非事務狀態切換至事務狀態,這一切是通過在客戶端狀態的flags屬性中打開REDIS_MULTI標識來完成的。

2)命令入隊

如果客戶端發送的命令為EXEC、DISCARD、WATCH、MULTI四個命令的其中一個,那麼伺服器立即執行這個命令,相反,伺服器並不會立即執行這個命令,而是將命令放入到一個事務隊列中,而後向客戶端返回QUEUED回覆。

每個Redis客戶端都有自己的事務狀態,這個事務狀態保存在客戶端狀態的mstate屬性裡面:

typedef struct redisClient{
    //事務狀態
    multiState mstate;
} redisClient;

事務狀態包含一個事務隊列,以及一個已入隊命令的計數器:

typedef struct multiState{
    //事務隊列,FIFO順序
    multiCmd *commands;
    ///已入隊列計數
    int count;
} multiState;
typedef struct multiCmd{
    //參數
    robj **argv;
    //參數數量
    int argc;
    //命令指針
    struct redisCommand *cmd;
} multiCmd;

事務隊列以先進先出的方式 保存入隊的命令。

3)執行事務

當一個處於事務狀態的客戶端向伺服器發送EXEC命令時,這個EXEC命令將立即被伺服器執行。伺服器會遍歷這個客戶端的事務隊列,執行隊列中保存的所有命令,最後將執行命令所得的結果全部返回給客戶端。

WATCH命令

watch命令是一個樂觀鎖,它可以在exec命令執行之前,監視任意數量的資料庫鍵,併在EXEC命令執行時,檢查被監視的鍵是否至少有一個已經被修改過,如果是的話,伺服器將拒絕執行事務,並向客戶端返回標識事務執行失敗的空回覆。

每個Redis資料庫都保存著一個watched_keys字典,這個鍵是某個被watch命令監視的數據資料庫鍵,而字典的值是一個鏈表,鏈表中記錄了所有被監視相應資料庫鍵的客戶端。

typedef struct redisDb{
    //正在被watch命令監視的鍵
    dict *watched_keys;
} redisDb;

監視機制的觸發:所有對資料庫進行修改的命令,在執行之後都會調用touchWatchKey函數對watched_keys字典進行檢查,查看是否在客戶端正在監視剛剛被命令修改過的資料庫鍵,如果有的話,那麼touchWatchKey函數會將監視被修改鍵的客戶端的REDIS_DIRTY_CAS標識打開,標識該客戶端的事務安全性已經被破壞。

 

判斷事務是否安全

當伺服器接收到一個客戶端發來的EXEC命令時,伺服器會根據客戶端是否打開REDIS_DIRTY_CAS標識來決定是否執行事務:如果客戶端的REDIS_DIRTY_CAS標識已經被打開,那麼說明客戶端所監視的鍵當中,至少有一個鍵已經被修改過了,在這種情況下,客戶端提交的事務已經不再安全,所以伺服器會拒絕執行客戶端提交的事務;如果客戶端REDIS_DIRTY_CAS標識沒有被打開,那麼說明客戶端監視的所有鍵都沒有被修改過,事務仍然是安全的,伺服器將執行客戶端提交的這個事務。

 

事務的ACID性質

原子性:Redis的事務和傳統的關係型資料庫事務最大的區別在於,Redis不支持事務回滾機制,事務隊列中的某個命令在執行期間出現錯誤,整個事務也會繼續執行下去,直到將事務隊列中的所有命令都執行完畢為止。

一致性:

1、入隊錯誤,如果一個事務在入隊命令的過程中,出現了命令不存在,或者命令的格式不正確的情況那麼Redis將拒絕執行這個事務

2、執行錯誤:執行過程中發生的錯誤都是一些不能再入隊時被伺服器發現的錯誤,這些錯誤只會在命令實際執行時被觸發;即使在事務的執行過程中發生了錯誤,伺服器也不會中斷事務的執行,他會繼續執行事務中餘下的其他命令,並且一致性的命令不會被出錯的命令影響。

3、伺服器停機:如果伺服器運行在無持久化的記憶體模式中,那麼重啟之後資料庫將是一片空白的,因此數據總是一致性的;如果伺服器運行了RDB模式下,那麼事務中途停機不會導致不一致性,因為伺服器可以根據現有的RDB文件來恢複數據,從而將資料庫還原到一個一致性的狀態。如果伺服器運行在APF模式下,那麼事務中途停機不會導致不一致性,因為伺服器可以根據現有的APF文件來恢複數據,從而將資料庫還原至一致的狀態。

隔離性:Redis使用單線程的方式執行事務,並且伺服器保證,在執行事務期間不會對事務中斷,因此,redis的事務總是以串列的方式運行,並且事務也總是具有隔離性的。

耐久性:Redis事務的耐久性由Redis所使用的持久化模式決定的,(不論Redis在什麼模式下運行,在一個事務的最後加上SAVE命令總可以保證事務的耐久性。)

 


每天學一點,總會有收穫。

 

說明:尊重作者知識產權,文中內容參考《Redis設計與實現》,僅在此做學習與大家分享。

 


 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本篇文章主要闡述了VirtualBox的使用,Linux的分區,CentOS7操作系統的安裝與IP配置,MobaXterm遠程工具的使用 ...
  • linux 用戶 1、用戶相關 1.1useradd useradd 選項 用戶名 1.2passwd passwd 選項 用戶名 1.3 例子: 1.3.1創建用戶testuser 主目錄為home/testuser useradd –d /home/testuser -m testuser 1. ...
  • 最近開始接觸websocket,第一次裝的時候,還是遇到了些問題,這裡記錄一下 1.從git下載uWebSockets 地址:https://github.com/uNetworking/uWebSockets git clone https://github.com/uNetworking/uWe ...
  • Linux基礎知識、Shell編程、Linux系統管理、Linux服務管理、MySQL資料庫管理、Linux集群、Linux虛擬化 ...
  • 本文主要闡述了UNIX與Linux發展史、開源軟體簡介、Linux應用領域 ...
  • 單行編輯控制項具有ES_密碼樣式。預設情況下,具有此樣式的編輯控制項為用戶鍵入的每個字元顯示一個星號。 但是,本例使用EM_SETPASSWORDCHAR消息將預設字元從星號更改為加號(+)。以下屏幕截圖顯示用戶輸入密碼後的對話框。 步驟1:創建密碼對話框的實例。 下麵的C++代碼示例使用DealBox ...
  • 最近安裝了datagrip操作達夢資料庫,發現有一個問題:dagagrip無法獲取dbms_output的輸出,在oracle是可以的,但在達夢不行。 於是聯想到一個問題:c語言裡面怎麼獲取dbms_output的輸出? 百度了一下,沒有找到明確的答案,但是找到了jdbc獲取dbms_output輸 ...
  • 安裝達夢windows版資料庫時,會附帶安裝一個資料庫管理工具。這個工具是我知道的,最全面的達夢資料庫可視化數據操作工具。、 除了支持常規的dml操作外,還支持存儲過程開發與調試,同時提供了簡單的操作歷史記錄查詢,sql自動補全,資料庫對象管理等功能。 但用慣了oracle的人,可能還是會更習慣PL ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...