Redis事務

一個事務從開始到執(zhí)行會經(jīng)歷以下三個階段:

1. 開始事務。

2. 命令入隊。

3. 執(zhí)行事務。

MULTI 命令的執(zhí)行標記著事務的開始

? ? ? 這個命令唯一做的就是,將客戶端的REDIS_MULTI 選項打開,讓客戶端從非事務狀態(tài)切換到事務狀態(tài)。當客戶端進入事務狀態(tài)之后,客戶端發(fā)送的命令就會被放進事務隊列里。

? ? ? ?但其實并不是所有的命令都會被放進事務隊列,其中的例外就是EXEC 、DISCARD 、MULTI和WATCH 這四個命令——當這四個命令從客戶端發(fā)送到服務器時,它們會像客戶端處于非事務狀態(tài)一樣,直接被服務器執(zhí)行,如下圖所示:

redis事務執(zhí)行流程

對于以下事務隊列:

事務入隊流程

? ? ? ? 程序會首先執(zhí)行SET 命令,然后執(zhí)行GET 命令,再然后執(zhí)行SADD 命令,最后執(zhí)行SMEMBERS命令。執(zhí)行事務中的命令所得的結果會以FIFO 的順序保存到一個回復隊列中。

事務狀態(tài)下的DISCARD 、MULTI 和WATCH 命令

? ? ? ? ?DISCARD 命令用于取消一個事務,它清空客戶端的整個事務隊列,然后將客戶端從事務狀態(tài)調整回非事務狀態(tài)。

? ? ? ? ?WATCH 命令用于在事務開始之前監(jiān)視任意數(shù)量的鍵:當調用EXEC 命令執(zhí)行事務時,如果任意一個被監(jiān)視的鍵已經(jīng)被其他客戶端修改了,那么整個事務不再執(zhí)行,直接返回失敗。

以下執(zhí)行序列展示了上面的例子是如何失敗的:

watch監(jiān)控

? ? ? ?在時間T4 ,客戶端B 修改了name 鍵的值,當客戶端A 在T5 執(zhí)行EXEC 時,Redis 會發(fā)現(xiàn)name 這個被監(jiān)視的鍵已經(jīng)被修改,因此客戶端A 的事務不會被執(zhí)行,而是直接返回失敗。

WATCH 命令的實現(xiàn)

? ? ? 在每個代表數(shù)據(jù)庫的redis.h/redisDb 結構類型中,都保存了一個watched_keys 字典,字典的鍵是這個數(shù)據(jù)庫被監(jiān)視的鍵,也就是說watch監(jiān)控事務中的key。如果這個被監(jiān)視的key被改動,那么會將這個key的客戶端的REDIS_DIRTY_CAS打開,如圖:

watch標記

? 當客戶端發(fā)送EXEC 命令、觸發(fā)事務執(zhí)行時,服務器會對客戶端的狀態(tài)進行檢查:

? ? ? ?如果客戶端的REDIS_DIRTY_CAS 選項已經(jīng)被打開,那么說明被客戶端監(jiān)視的鍵至少有一個已經(jīng)被修改了,事務的安全性已經(jīng)被破壞。服務器會放棄執(zhí)行這個事務,直接向客戶端返回空回復,表示事務執(zhí)行失敗。

? ? ? 如果REDIS_DIRTY_CAS 選項沒有被打開,那么說明所有監(jiān)視鍵都安全,服務器正式執(zhí)行事務。

事務的ACID 性質

? ? ? ?單個Redis 命令的執(zhí)行是原子性的,但Redis 沒有在事務上增加任何維持原子性的機制,所以Redis 事務的執(zhí)行并不是原子性的。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 如果一個事務隊列中的所有命令都被成功地執(zhí)行,那么稱這個事務執(zhí)行成功。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 另一方面,如果Redis 服務器進程在執(zhí)行事務的過程中被停止——比如接到KILL 信號、宿主機器停機,等等,那么事務執(zhí)行失敗。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?當事務失敗時,Redis 也不會進行任何的重試或者回滾動作。

一致性(Consistency)

Redis 的一致性問題可以分為三部分來討論:入隊錯誤、執(zhí)行錯誤、Redis 進程被終結。? ? ? ? ? ? ? ? ?

入隊錯誤

在命令入隊的過程中, 如果客戶端向服務器發(fā)送了錯誤的命令, 比如命令的參數(shù)數(shù)量不對,等等,那么服務器將向客戶端返回一個出錯信息,并且將客戶端的事務狀態(tài)設為REDIS_DIRTY_EXEC 。

? ? ? ?當客戶端執(zhí)行EXEC 命令時,Redis 會拒絕執(zhí)行狀態(tài)為REDIS_DIRTY_EXEC 的事務,并返回失敗信息。

redis 127.0.0.1:6379> MULTI? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?OK? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? redis 127.0.0.1:6379> set key? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (error) ERR wrong number of arguments for 'set' command? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? redis 127.0.0.1:6379> EXISTS key? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?QUEUED? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? redis 127.0.0.1:6379> EXEC? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (error) EXECABORT Transaction discarded because of previous errors.

因此,帶有不正確入隊命令的事務不會被執(zhí)行,也不會影響數(shù)據(jù)庫的一致性。

執(zhí)行錯誤

? ? ? 如果命令在事務執(zhí)行的過程中發(fā)生錯誤,比如說,對一個不同類型的key 執(zhí)行了錯誤的操作。? ? ? ? ? 那么Redis 只會將錯誤包含在事務的結果中,這不會引起事務中斷或整個失敗,不會影響已執(zhí)行事務命令的結果,也不會影響后面要執(zhí)行的事務命令,所以它對事務的一致性也沒有影響。

Redis 進程被終結? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如果Redis 沒有采取任何持久化機制,那么重啟之后的數(shù)據(jù)庫總是空白的,如果有使用rdb或者aof,那么在此啟動會還原數(shù)據(jù)。

隔離性(Isolation)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Redis在執(zhí)行事務時,不會對事務進行中斷,事務可以運行直到執(zhí)行完所有事務隊列中的命令為止。因此,Redis 的事務是總是帶有隔離性的。

持久性(Durability)? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?事務的持久性由Redis 所使用的持久化模式?jīng)Q定。


參考資料:《Redis的設計與實現(xiàn)》

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容