Redis:17---常用功能之(事務)

  • 為了保證多條命令組合的原子性,Redis提供了簡單的事務功能以及集成Lua腳本來解決這個問題,本文介紹Redis事務,Lua在下一篇文章介紹

一、事務概述

  • 簡單地說,事務表示一組動作,要么全部執行,要么全部不執行。例如在社交網站上用戶A關注了用戶B,那么需要在用戶A的關注表中加入用戶B,并且在用戶B的粉絲表中添加用戶A,這兩個行為要么全部執行,要么全部不執行,否則會出現數據不一致的情況

  • Redis只提供了四個命令管理事務:

    • MULTI:用來開啟一個事務。開啟一個事務之后,輸入的命令不會被立即執行,而是進入事務隊列中(入隊),所以可以看見輸入命令的結果顯示為“QUEUED”

    • WATCH:是一個樂觀鎖。它可以在EXEC命令執行之前,監視任意數量的數據庫鍵,并在EXEC命令執行時,檢查被監視的鍵是否至少有一個已經被修改過了,如果是的話,服務器將拒絕執行事務,并向客戶端返回代表事務執行失敗的空回復

    • DISCARD:用于取消本次事務,放棄執行事務塊內的所有命令。如果使用了WATCH,DISCARD將取消監視連接監視的所有鍵

    • EXEC:提交一個事務

  • 所以Redis的事務比較簡單,主要是因為它不支持事務中的回滾特性,同時無法實現命令之間的邏輯關系計算,當然也體現了Redis的“keep it simple”的特性

二、事務演示案例

MULTI+EXEC

  • 下面使用MULTI開啟一個事務,并且執行相關操作,最后使用EXEC提交執行事務內的操作

  • 備注:可以看到事務開啟之后,每次執行的命令結果都會顯示QUEUED,表示命令入隊,但是沒有被執行

MULTI+DISCARD

  • 下面使用MULTI開啟一個事務,并且執行相關操作,最后使用DISCARD終止本次事務,并且事務內的操作全部放棄執行

  • 備注:因為discard已經結束事務了,所以再次輸入exec會顯示沒有匹配的multi

MULTI+WATCH+EXEC

  • 客戶端1:先設置一個字符串,鍵名為key,然后使用watch監聽該鍵。然后開啟事務

  • 客戶端2:在客戶端1事務還未結束的時候,修改key

  • 客戶端1:操作key,并提交事務。因為key被其他客戶端修改,所以EXEC返回nil,事務沒有被執行。然后獲取key,key沒有被改變

三、事務錯誤的處理

  • 如果事務中出現錯誤,那么Reiis的處理機制也不盡相同

①命令錯誤

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

  • 例如:下面操作錯將set寫成了sett,屬于語法錯誤,會造成整個事務無法執行,key和counter的值未發生變化:

????? ?根據文檔記錄,在Redis 2.6.5以前的版本,即使有命令在入隊過程中發生了錯誤, 事務一樣可以執行,不過被執行的命令只包括那些正確入隊的命令,以下這段代碼是 在Redis 2.6.4版本上測試的,可以看到事務可以正常執行,但只有成功入隊的SET命令 和GET命令被執行了,而錯誤的YAH000O則被忽略了:

redis> MULTI
OK
redis> SET msg "hello"
QUEUED
redis> YAH000O
(error) ERR unknown command ' YAH000O'
redis> GET msg
QUEUED
redis> EXEC
11 OK
2) "hello"

②運行時錯誤(執行錯誤)

  • 有些事務輸入的命令沒有錯誤,但是語法或邏輯有錯誤,這類錯誤不會被立即檢測出來,只有當事務提交時才會被檢測出來

  • 即使在事務的執行過程中發生了錯誤,服務器也不會中斷事務的執行,它會繼續執行事務中余下的其他命令,并且已執行的命令(包括執行命令所產生的結果)不會被出錯的命令影響

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

③服務器停機

  • 如果Redis服務器在執行事務的過程中停機,那么根據服務器所使用的持久化模式,可能有以下情況出現:

    • 如果服務器運行在無持久化的內存模式下,那么重啟之后的數據庫將是空白的,因此數據總是一致的

    • 如果服務器運行在RDB模式下,那么在事務中途停機不會導致不一致性,因為服務器可以根據現有的RDB文件來恢復數據,從而將數據庫還原到一個一致的狀態。如果找不到可供使用的RDB文件,那么重啟之后的數據庫將是空白的,而空白數據庫總是一致的

    • 如果服務器運行在AOF模式下,那么在事務中途停機不會導致不一致性,因為服務器可以根據現有的AOF文件來恢復數據,從而將數據庫還原到一個一致的狀態。如果找不到可供使用的AOF文件,那么重啟之后的數據庫將是空白的,而空白數據庫總是一致的

  • 綜上所述,無論Redis服務器運行在哪種持久化模式下,事務執行中途發生的停機都不會影響數據庫的一致性

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

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

相關文章

leetcode448. 找到所有數組中消失的數字 天秀記錄法

給定一個范圍在 1 ≤ a[i] ≤ n ( n 數組大小 ) 的 整型數組,數組中的元素一些出現了兩次,另一些只出現一次。 找到所有在 [1, n] 范圍之間沒有出現在數組中的數字。 您能在不使用額外空間且時間復雜度為O(n)的情況下完成這個任務嗎? 你可以假定返回…

Redis:12---有序集合對象

一、有序集合對象概述它保留了集合不能有重復成員的特性, 但不同的是,有序集合中的元素可以排序。但是它和列表使用索引下標作為排序依據不同的是,它給每個元素設置一個分數(score)作為排序的依據如下圖所示&#xff0…

Redis:14---常用功能之(Pipeline)

一、Pipeline概述 Redis客戶端執行一條命令分為如下四個過程:1.發送命令2.命令排隊3.命令執行4.返回結果其中1+4稱為Round Trip Time(RTT,往返時間)Pipeline概述 Redis提供了批量操作命令(例如mget、mset等),有效地節約RTT。但大部分命令是不支持批量操作的,例如要執行…

leetcode170. 兩數之和 III - 數據結構設計

設計并實現一個 TwoSum 的類,使該類需要支持 add 和 find 的操作。 add 操作 - 對內部數據結構增加一個數。 find 操作 - 尋找內部數據結構中是否存在一對整數,使得兩數之和與給定的數相等。 示例 1: add(1); add(3); add(5); find(4) -> true fi…

Redis:11---Set對象

集合類型 (Set) 是一個無序并唯一的鍵值集合。它的存儲順序不會按照插入的先后順序進行存儲。 集合類型和列表類型的區別如下: 列表可以存儲重復元素,集合只能存儲非重復元素;列表是按照元素的先后順序存儲元素的,而集合則是無序方式存儲元素的。一、集合對象概述 特點:集…

Oracle中計算兩個時間的時間差:

計算時間差是oracledata數據類型的一個常見問題。oracle支持日期計算,你可以創建諸如“日期1-日期2”這樣的表達式來計算這兩個日期之間的時間差。一旦你發現了時間差異,你可以使用簡單的技巧來以天、小時、分鐘或者秒為單位來計算時間差。為…

Redis:13--常用功能之redis-cli redis-server等命令

Redis提供了redis-cli、redis-server、redis-benchmark等Shell工具。它們 雖然比較簡單,但是麻雀雖小五臟俱全,有時可以很巧妙地解決一些問題一、redis-cli在前面數據庫連接的時候已經redis-cli的-h、-p參數,除了這些參數,還有很多…

Redis:16---常用功能之(慢查詢日志)

一、慢查詢日志介紹 許多存儲系統(例如MySQL)提供慢查詢日志幫助開發和運維人員定位系統存在的慢操作。所謂慢查詢日志就是系統在命令執行前后計算每條命令的執行時間,當超過預設閥值,就將這條命令的相關信息記錄下來,Redis也提供了類似的功能Redis的慢查詢日志功能用于記…

leetcode256. 粉刷房子

假如有一排房子,共 n 個,每個房子可以被粉刷成紅色、藍色或者綠色這三種顏色中的一種,你需要粉刷所有的房子并且使其相鄰的兩個房子顏色不能相同。 當然,因為市場上不同顏色油漆的價格不同,所以房子粉刷成不同顏色的花…

Redis:21---客戶端相關配置篇

一、客戶端相關配置①客戶端的限制maxclientsRedis提供了maxclients參數來限制最大客戶端連接數,一旦連接數超過 maxclients,新的連接將被拒絕maxclients默認值是10000可以通過info clients來查詢當前Redis的連接數:可以通過config set maxcl…

Redis:23---info命令總結

info命令的格式有3種:info:部分Redis系統狀態統計信息info all:全部Redis系統狀態統計信息,一次性打印下面所有p的內容info p:某一塊的系統狀態統計信息。info命令所有的p如下所示模塊名模塊含義 Server服務器信息Clie…

Redis:22---客戶端API:client、monitor)

一、client listclient list命令能列出與Redis服務端相連的所有客戶端連接信息。例如下面代碼是在一個Redis實例上執行client list的結果,其中每一行代表一個客戶端信息:下面將選擇幾個重要的屬性進行說明,其余通過表格的形式進行展示①標識&…

leetcode175. 組合兩個表(SQL)

表1: Person ---------------------- | 列名 | 類型 | ---------------------- | PersonId | int | | FirstName | varchar | | LastName | varchar | ---------------------- PersonId 是上表主鍵 表2: Address ---------------------- | 列名 …

Redis:20---常用功能之(發布與訂閱)

一、發布與訂閱概述Redis提供了基于“發布/訂閱”模式的消息機制,此種模式下,消息發布者和訂閱者不進行直接通信,發布者客戶端向指定的頻道(channel)發布消息,訂閱該頻道的每個客戶端都可以收到該消息。 下…

Redis:19---常用功能之(HyperLogLog)

一、HyperLogLog概述HyperLogLog并不是一種新的數據結構(實際類型為字符串類型),而是一種基數算法,通過HyperLogLog可以利用極小的內存空間完成獨立總數的統計,數據集可以是IP、Email、ID等HyperLogLog提供了3個命令&a…

計算時間差的Oracle函數

Oracle函數可以實現諸多的功能,下面就介紹使用Oracle函數計算時間差的實現方法,如果您對Oracle函數方面感興趣的話,不妨一看。 兩個Date類型字段:START_DATE,END_DATE,計算這兩個日期的時間差(分…

leetcode181. 超過經理收入的員工(SQL)

Employee 表包含所有員工,他們的經理也屬于員工。每個員工都有一個 Id,此外還有一列對應員工的經理的 Id。 ------------------------------ | Id | Name | Salary | ManagerId | ------------------------------ | 1 | Joe | 70000 | 3 |…

UNIX(多線程):01---線程簡介及線程限制

一、線程的概念 典型的UNIX進程可以看成只有一個控制線程:一個進程在同一時刻只做一件事。有了多個控制線程后,在程序設計時可以把進程設計成在同一時刻能夠做不止一件事,每個線程處理各自獨立的任務二、線程的優點 通過為每種事件類型分配單獨的處理線程,可以簡化處理異步…

UNIX(多線程):13---condition_variable、wait、notify_one、notify_all

條件變量std::condition_variable、wait()、notify_one() 線程A: 等待一個條件滿足線程B: 專門往消息隊列中放入消息(數據),達到一定條件,通知處于等待中的線程A。std::condition_variable實際上是一個類,是一個和條件相關的一個類,說白了就是等待一個條件達成。這個類是…

leetcode176. 第二高的薪水(SQL)

編寫一個 SQL 查詢,獲取 Employee 表中第二高的薪水(Salary) 。 ------------ | Id | Salary | ------------ | 1 | 100 | | 2 | 200 | | 3 | 300 | ------------ 例如上述 Employee 表,SQL查詢應該返回 200 作為第二…