中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Redis事務基本指令有哪些

發布時間:2022-11-01 17:50:45 來源:億速云 閱讀:165 作者:iii 欄目:關系型數據庫

本篇內容主要講解“Redis事務基本指令有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Redis事務基本指令有哪些”吧!

Redis 事務簡介

Redis 只是提供了簡單的事務功能。其本質是一組命令的集合,事務支持一次執行多個命令,在事務執行過程中,會順序執行隊列中的命令,其他客戶端提交的命令請求不會插入到本事務執行命令序列中。命令的執行過程是順序執行的,但不能保證原子性。無法像 MySQL 那樣,有隔離級別,出了問題之后還能回滾數據等高級操作。后面會詳細分析。

Redis 事務基本指令

Redis 提供了如下幾個事務相關的基礎指令。

MULTI開啟事務,Redis 會將后續命令加到隊列中,而不真正執行它們,直到后續使用EXEC來原子化的順序執行這些命令 EXEC執行所有事務塊內的命令 DISCARD取消事務,放棄執行事務塊內所有的命令 WATCH監視一個或多個 key,若事務在執行前,這些 key 被其他命令修改,則事務被終端,不會執行事務中的任何命令 UNWATCH取消 WATCH命令對所有 keys 的監視

一般情況下,一個簡單的 Redis 事務主要分為如下幾個部分:

執行命令MULTI開啟一個事務。 開啟事務之后,執行命令的多個命令會依次被放入一個隊列,放入成功則會返回QUEUED消息。 執行命令EXEC提交事務,Redis 會依次執行隊列中的命令,并依次返回所有命令的結果。(若想放棄提交事務,則執行DISCARD)。

下圖簡單介紹了下 Redis 事務執行的過程:

Redis事務基本指令有哪些

實例分析

下面我們來通過一些實際具體例子,來體會下 Redis 中的事務。前面我們也說到 Redis 的事務不是正真的事務,是無法完全滿足標準事務的ACID特性的。通過下面的例子,我們來看看,Redis 的“破產版”事務到底存在什么問題。

[A]正常執行提交

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET a 1
QUEUED
127.0.0.1:6379> SET b 2
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
127.0.0.1:6379> GET a
"1"
127.0.0.1:6379> GET b
"2"

開啟事務后,提交的命令都會加入隊列(QUEUED),執行 EXEC 后會逐步執行命令并返回結果。這個看起來是不是和我們平時使用 MySQL 的事務操作相似,類似 start transaction 和 commit。

[B]正常取消事務

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET a 1
QUEUED
127.0.0.1:6379> SET b 2
QUEUED
127.0.0.1:6379> DISCARD
OK
127.0.0.1:6379> 
127.0.0.1:6379> GET a
(nil)
127.0.0.1:6379> GET b
(nil)

開啟事務后,若不想繼續事務,使用 DISCARD 取消,前面提交的命令并不會真正執行,相關的 key 值不變。這個看起來也和 MySQL 的事務相似,類似 start transaction 和 rollback。

[C]WATCH 監視 key

-- 線程 1 中執行
127.0.0.1:6379> del a
(integer) 1
127.0.0.1:6379> get a
(nil)
127.0.0.1:6379> SET a 0
OK
127.0.0.1:6379> WATCH a
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET a 1
QUEUED
----------------------------------------- 線程 2 中執行
----------------------------------------- 127.0.0.1:6379> SET a 2
----------------------------------------- OK
127.0.0.1:6379> EXEC
(nil)
127.0.0.1:6379> GET a
"2"

在開啟事務之前 WATCH 了 a 的值,隨后再開啟事務。在另一個線程中設置了 a 的值(SET a 2),然后再 EXEC 執行事務,結果為 nil,
說明事務沒有被執行。因為 a 的值在 WATCH 之后發生了變化,所以事務被取消了。

需要注意的是,這里和開啟事務的時間點沒有關系,與 MULTI 和另一個線程設置 a 的值的先后沒有關系。只要是在 WATCH 之后發生了變化。無論事務是否已經開啟,執行事務(EXEC)的時候都會取消。
普通情況下,在執行 EXEC 和 DISCARD 命令時,都會默認執行 UNWATCH。

[D]語法錯誤

127.0.0.1:6379> SET a 1
OK
127.0.0.1:6379> SET b 2
OK
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET a 11
QUEUED
127.0.0.1:6379> SETS b 22
(error) ERR unknown command 'SETS'
127.0.0.1:6379> EXEC
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> GET a
"1"
127.0.0.1:6379> GET b
"2"

當 Redis 開啟一個事務后,若添加的命令中有語法錯誤,會導致事務提交失敗。這種情況下事務隊列中的命令都不會被執行。如上面例子中 a 和 b 的值都是原有的值。
這類在 EXEC 之前產生的錯誤,如命令名稱錯誤,命令參數錯誤等,會在 EXEC 執行之前被檢測出來,所以在發生這些錯誤的時候,事務會被取消,事務中的所有命令都不會執行。(這種情況看起來是不是有點像回滾了)

[E]運行時錯誤

127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> SET a 1
QUEUED
127.0.0.1:6379> SET b hello
QUEUED
127.0.0.1:6379> INCR b
QUEUED
127.0.0.1:6379> EXEC
1) OK
2) OK
3) (error) ERR value is not an integer or out of range
127.0.0.1:6379> GET a
"1"
127.0.0.1:6379> GET b
"hello"

當 Redis 開啟一個事務后,添加的命令沒有出現前面說的語法錯誤,但是在運行時檢測到了類型錯誤,導致事務最提交失敗(說未完全成功可能更準確點)。此時事務并不會回滾,而是跳過錯誤命令繼續執行。
如上面的例子,未報錯的命令值已經修改,a 被設置成了 1,b 被設置為了 hello,但是報錯的值未被修改,即 INCR b 類型錯誤,并未執行,b 的值也沒有被再更新。

Redis 事務與 ACID

通過上面的例子,我們已經知道 Redis 的事務和我們通常接觸的 MySQL 等關系數據庫的事務還有有一定差異的。它不保證原子性。同時 Redis 事務也沒有事務隔離級別的概念。下面我們來具體看下 Redis 在 ACID 四個特性中,那些是滿足的,那些是不滿足的。
事務執行可以分為命令入隊(EXEC 執行前)和命令實際執行(EXEC 執行之后)兩個階段。下面我們在分析的時候,很多時候都會分這兩種情況來分析。

原子性(A)

上面的實例分析中,[A],[B],[C]三種正常的情況,我們可以很明顯的看出,是保證了原子性的。
但是一些異常情況下,是不滿足原子性的。

如 [D] 所示的情況,客戶端發送的命令有語法錯誤,在命令入隊列時 Redis 就判斷出來了。等到執行 EXEC 命令時,Redis 就會拒絕執行所有提交的命令,返回事務失敗的結果。此種情況下,事務中的所有命令都不會被執行了,是保證了原子性的。 如 [E] 所示的情況,事務操作入隊時,命令和操作類型不匹配,此時 Redis 沒有檢查出錯誤(這類錯誤是運行時錯誤)。等到執行 EXEC 命令后,Redis 實際執行這些命令操作時,就會報錯。需要注意的是,雖然 Redis 會對錯誤的命令報錯不執行,但是其余正確的命令會依次執行完。此種情況下,是無法保證原子性的。 在執行事務的 EXEC 命令時,Redis 實例發生了故障,導致事務執行失敗。此時,如果開啟了 AOF 日志,那么只會有部分事務操作被記錄到 AOF 日志中。使用redis-check-aof工具檢測 AOF 日志文件,可以把未完成的事務操作從 AOF 文件中去除。這樣一來,使用 AOF 文件恢復實例后,事務操作不會被再執行,從而保證了原子性。若使用的 RDB 模式,最新的 RDB 快照是在 EXEC 執行之前生成的,使用快照恢復之后,事務中的命令也都沒有執行,從而保證了原子性。若 Redis 沒有開啟持久化,則重啟后內存中的數據全部丟失,也就談不上原子性了。 一致性(C)

一致性指的是事務執行前后,數據符合數據庫的定義和要求。這點在 Redis 事務中是滿足的,不論是發生語法錯誤還是運行時錯誤,錯誤的命令均不會被執行。

EXEC 執行之前,入隊報錯(實例分析中的語法錯誤)

事務會放棄執行,故可以保證一致性。

EXEC 執行之后,實際執行時報錯(實例分析中的運行時錯誤)

錯誤的命令不會被執行,正確的命令被執行,一致性可以保證。

EXEC 執行時,實例宕機

若 Redis 沒有開啟持久化,實例宕機重啟后,數據都沒有了,數據是一致的。
若配置了 RDB 方式,RDB 快照不會在事務執行時執行。所以,若事務執行到一半,實例發生了故障,此時上一次 RDB 快照中不會包含事務所做的修改,而下一次 RDB 快照還沒有執行,實例重啟后,事務修改的數據會丟失,數據是一致的。若事務已經完成,但新一次的 RDB 快照還沒有生成,那事務修改的數據也會丟失,數據也是一致的。
若配置了 AOF 方式。當事務操作還沒被記錄到 AOF 日志時,實例就發生故障了,使用 AOF 日志恢復后數據是一致的。若事務中的只有部分操作被記錄到 AOF 日志,可以使用 redis-check-aof清除事務中已經完成的操作,數據庫恢復后數據也是一致的。

隔離性(I) 并發操作在 EXEC 執行前,隔離性需要通過 WATCH 機制來保證 并發操作在 EXEC 命令之后,隔離性可以保證

情況 a 可以參考前面的實例分析 WATCH 命令的使用。
情況 b,由于 Redis 是單線程執行命令,EXEC 命令執行后,Redis 會保證先把事務隊列中的所有命令執行完之后再執行之后的命令。

持久性(D)

若 Redis 沒有開啟持久化,那么就是所有數據都存儲在內存中,一旦重啟,數據就會丟失,因此此時事務的持久性是肯定無法得到保證的。
若 Redis 開啟了持久化,當實例宕機重啟,還是會有可能丟失數據,因此也并能完全保證持久性。
因此,我們可以說 Redis 事務無法一定保證持久性,僅在特殊的情況下,可以保證持久性。

關于 Redis 在開啟持久化之后,為啥還會丟失數據,筆者會單獨整理一篇 Redis 持久化與主從相關的文章來介紹,此處簡單說下。
如果配置了 RDB 模式,在一個事務執行后,下一次 RDB 快照還未執行前,Redis 實例發生了宕機,數據就會丟失、
如果配置了 AOF 模式,而 AOF 模式的三種配置選項 no,everysec,always 也都可能會產生數據丟失的情況。

總結一下,Redis 事務對 ACID 的支持情況:

具備一定的原子性,但不支持回滾 滿足一致性 滿足隔離性 無法保證持久性 Redis 事務為什么不支持回滾

看一下官網的的說明:

What about rollbacks?
Redis does not support rollbacks of transactions since supporting rollbacks would have a significant impact on the simplicity and performance of Redis.

Redis事務基本指令有哪些

大部分需要事務回滾的情況是程序錯誤導致的,這種情況一般是開發環境,生產環境不應該出現這種錯誤。
對于邏輯錯誤,例如應該加 1,結果寫成了加 2,這種情況無法通過回滾來解決。
Redis 追求的是簡單高效,而傳統事務的實現相對復雜很多,這和 Redis 的設計思想是違背的。當我們享受 Redis 的快速時,也就無法再要求它更多。

到此,相信大家對“Redis事務基本指令有哪些”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

井冈山市| 平利县| 平泉县| 荥阳市| 武清区| 安西县| 扎兰屯市| 芜湖市| 元阳县| 屯昌县| 垦利县| 拜泉县| 永善县| 内丘县| 宝清县| 雷波县| 青龙| 太仆寺旗| 永泰县| 丹江口市| 青海省| 乌苏市| 克拉玛依市| 黄大仙区| 镶黄旗| 馆陶县| 新营市| 兴义市| 巴青县| 阳谷县| 开鲁县| 同仁县| 确山县| 盐城市| 大同市| 靖边县| 武陟县| 金塔县| 呼伦贝尔市| 特克斯县| 营口市|