日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Redis中的事务

發布時間:2023/12/9 数据库 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Redis中的事务 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Redis中的事務

參考

參考博客:https://blog.csdn.net/jiayi_yao/article/details/124689937

菜鳥教程:https://www.runoob.com/redis/redis-transactions.html

參考博客:https://blog.csdn.net/weixin_46156200/article/details/121043694?spm=1001.2101.3001.6661.1&utm_medium=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-121043694-blog-124689937.pc_relevant_aa&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-2%7Edefault%7ECTRLIST%7Edefault-1-121043694-blog-124689937.pc_relevant_aa&utm_relevant_index=1

參考書籍:《Redis設計與實現》

Redis事務基本概念

Redis的事務是什么?

Redis事務是指將多條命令加入隊列,一次批量執行多條命令,每條命令會按順序執行,事務執行過程中不會受客戶端傳入的命令請求影響。

一個事務從開始到執行會經歷以下三個階段:

  • 第一階段:開始事務(其實就是修改Redis客戶端中關于事務狀態的flag)
  • 第二階段:命令入隊(事務狀態下,非WATCH、EXEC、DISCARD、MULTI都不會執行,而是加入事務隊列)
  • 第三階段、執行事務。(給出EXEC指令)
  • EXEC:創建回復隊列,依次遍歷事務隊列,取得結果放入回復隊列,執行完畢后,清空事務隊列,修改Redis客戶端狀態為非事務狀態(非事務狀態,接到命令就會立即執行),然后將回復隊列返回給前端

  • 第三階段、執行事務。
  • Redis事務的相關命令如下:

    MULTI:標識一個事務的開啟,即開啟事務;
    EXEC:執行事務中的所有命令,即提交;
    DISCARD:放棄事務;和回滾不一樣,Redis事務不支持回滾。
    WATCH:監視Key改變,用于實現樂觀鎖。如果監視的Key的值改變,事務最終會執行失敗。
    UNWATCH:放棄監視。

    使用WATCH實現樂觀鎖

    說到樂觀鎖,就和悲觀鎖一起簡單說說對其的理解:

    樂觀鎖:就是非常樂觀,做什么事都往好處想; 對于數據庫操作,就認為每次操作數據的時候都認為別的操作不會修改,所以不會加鎖,而是通過一個類似于版本的字段來標識該數據是否修改過,在執行本次操作前先判斷是否修改過,如果修改過就放棄本次操作重新再來。樂觀鎖適用于多讀的應用類型,這樣可以提高吞吐量;樂觀鎖策略:提交版本必須大于記錄當前版本才能執行更新。

    悲觀鎖:就是非常悲觀,做什么事都覺得不好;對于數據庫操作,每次操作數據數據都會認為別的操作會修改當前數據,所以都要對其進行加鎖,類似于表鎖和行鎖。

    WATCH通過監視指定Redis Key,如果沒有改變,就執行成功,如果發現對應值發生改變,事務就會執行失敗。

    (WATCH命令一般在開啟事務之前使用)

    那會一直監視指定的Key嗎?,答案是不會的,以下三種方式可以取消監視:

    • 事務執行之后,不管是否執行成功還好是失敗,都會取消對應的監視;
    • 當監視的客戶端斷開連接時,也會取消監視;
    • 可以手動UNWATCH取
    • 消所有Key的監視;

    WATCH如何實現?

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

    通過watched_keys字典,服務器可以清楚地知道,那些數據庫鍵正在被監視,以及那些客戶端在監視。

    監視機制的觸發

    所有對數據庫修改的命令,例如SET、LPUSH、SADD等,在執行之后都會調用multi.c/touchWatchKey函數對watched_keys字典進行檢查,查看是否有客戶端正在監視剛剛修改的數據庫鍵,如果有,那么touchWatchKey函數會將監視被修改的客戶端的REDIS_DIRTY_CAS表示打開,表示該客戶端的數據安全性已經被破壞。

    判斷事務是否安全

    當客戶端接收到一個客戶端發來的EXEC命令時,服務器會根據這個客戶端是否打開了REDIS_DIRTY_CAS來決定是否會執行該事務:

    • 如果客戶端的REDIS_DIRTY_CAS表示已經被打開,那么說明這個客戶端監視的鍵中,至少有一個已經被修改了,這種情況下,客戶端提交的事務已經不安全了,所以服務器會拒絕執行客戶端提交的事務
    • 如果客戶端的REDIS_DIRTY_CAS表示沒有被打開,說明客戶端監視的所有的鍵都沒有被修改(或者這個事務沒有監視任何鍵),事務仍然是安全的,服務器將執行客戶端提交的這個事務

    事務的ACID性質

    在Redis中,事務總是具有原子性,一致性,隔離性,在某些特定的持久化模式下,事務也具有持久性。

    原子性

    事務具有原子性是指得是,數據庫事務中的一個操作會當作一個整體來執行,服務器要么所有操作都執行,要么都不執行。

    對于Redis事務來說,事務中的命令要么全部執行,要么全不執行,因此Redis事務是具有一定的原子性的。Redis事務和傳統事務最大的區別是,Redis不支持事務回滾機制,即使事務隊列中有一個操作執行中發生錯誤,整個事務還會繼續執行,直到所有事務執行完畢,并且之前執行的命令也不會受到影響。

    Redis事務中沒有提供回滾的支持,官方提供了理由:

    不支持事務回滾是因為這種復雜的功能和Redis追求的簡單高效不相符,他認為Redis事務執行錯誤,通常都是編程錯誤產生的,這種錯誤通常只會出現在開發環境,而很少會出現在實際的生產環境,沒有必要增加回滾功能。

    一致性

    事務具有一致性指的是,如果數據庫在執行事務前是一致的,那么執行事務后,無論成功與否,也應該是一致的。“一致”指的是數據符合數據庫本身的定義和要求,沒有包含非法或者無效的錯誤數據。

    Redis通過謹慎的錯誤檢測和簡單的設計來保證事務的一致性。之后將介紹幾個事務可能出錯的地方,來說明Redis如何保證事務的一致性。

    入隊錯誤

    如果一個事務在入隊命令的時候,出現了命令不存在或者命令格式不存在等請況,那么Redis將拒絕執行這個事務。因為服務器拒絕執行入隊過程中出現錯誤的事務,所以Redis事務一致性不會被有入隊錯誤的事務影響。

    執行錯誤

    執行時錯誤,就是那種無法在入隊時被服務器發現的錯誤,這些問題只會實際使用的時候觸發。即使事務在執行的過程中發生了錯誤,服務器也不會中斷事務地執行,它會繼續執行剩下的命令,并且已執行的命令不會被出錯的命令影響。

    因為在事務的執行過程中,出錯的命令會被服務器識別出來,并進行相應的錯誤處理,所以這些出錯的命令不會對數據庫做任何修改,也不會對事務的一致性產生影響。

    服務器宕機

    如果Redis執行過程中宕機,根據服務器使用的持久化模式,可能出現以下情況:

    • 如果服務器運行在無持久化的內存模式下,那么重啟之后的數據庫是空白的,因此數據總是一致
    • 如果服務運行在RDB模式下,那么事務中途停機不會導致不一致性,因為服務器可以根據現有的RDB文件來恢復數據,并且事務執行過程中不會進行RDB,所以恢復后的數據庫能到達一個一致的狀態。如果找不到可用的RDB文件,那么數據庫就是空白的,空白的數據庫總是一致的。
    • 如果服務器運行在AOF模式下,那么在事務中途不會導致不一致性,因為服務器可以根據AOF文件來恢復數據,從而將數據庫庫恢復到一個一致的狀態,如果有部分數據寫入到了AOF,我們可以通過redis-check-aof清除已完成的一些操作,來保證一致性。

    綜上,服務器無論在哪種持久化方式下,事務中途停止都不會影響一致性。

    隔離性

    事務的隔離性指的是,即使數據庫中有多個事務并發地執行,各個事務之間也不會相互影響,并且在并發狀態下執行的事務和串行下的結果完全相同。

    因為Redis是單線程來執行,并且服務器抱枕,執行事務期間,不會對事務進行中斷,因此Redis事務總是以串行的方式運行,并且事務也總是具有隔離性。

    持久性

    事物的持久性是指,當事務執行完畢,執行這個事務所得的結果都保存到非易失存儲器上,即使服務器停機,執行事務得到的結果也不會丟失。

    因為Redis事務至少用隊列包裹了一組Redis命令,Redis并沒有為事務提供持久化功能,所以Redis事務的持久性就由Redis采用的持久化方式決定:

    • 服務器無任何持久化方式,事務不具有持久性,服務器停機,數據消失
    • 當服務器采用RDB持久方式時,服務器只會在特定的保存條件被滿足時,執行BGSAVE命令,對數據庫進行保存操作,異步執行的BGSAVE不能保證事務的結果第一時間寫入到硬盤,所以不具備持久性
    • 采用AOF方式,且appendsync=always,每次執行命令,就調用同步函數存入硬盤,所以具有持久性
    • 采用AOF方式,且appendsync=everysync,程序一秒同步一次,所以可能會導致修改丟失,所以不具有持久性
    • 采用AOF方式,且appendsync=no,交給服務器來判斷同步時機,所以可能會導致修改丟失,所以不具有持久性

    Redis事務優缺點

    優點:

    一次性按順序執行多個Redis命令,不受其他客戶端命令請求影響;
    事務中的命令要么都執行(命令間執行失敗互相不影響),要么都不執行(比如中間有命令語法錯誤);

    缺點:

    事務執行時,不能保證原子性;
    命令入隊每次都需要和服務器進行交互,增加帶寬(可以使用LUA腳本,一次發送所有的命令,減少帶寬);

    注意:

    當事務中命令語法使用錯誤時,最終會導致事務執行不成功,即事務內所有命令都不執行;
    當事務中命令知識邏輯錯誤,就比如給字符串做加減乘除操作時,只能在執行過程中發現錯誤,這種事務執行中失敗的命令不影響其他命令的執行。

    Redis事務應用場景

    Redis事務因為特性的原因,沒有什么應用場景,如果大家有了解的應用場景,歡迎補充。

    總結

    以上是生活随笔為你收集整理的Redis中的事务的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。