1、概述數據庫
和傳統關係型數據庫同樣,Redis 一樣是支持事務的。Redis 的事務能夠經過 MULTI/EXEC/DISCARD/WATCH 等命令來實現。編程
2、事務的 ACID 特性服務器
1). 原子性:事務中的命令要麼所有執行,要麼都不執行。併發
Redis 的事務和傳統的關係型數據庫事務最大的區別在於:Redis 事務不支持回滾,即便事務隊列中某個命令執行期間出現了錯誤,整個事務也會繼續執行下去,知道事務隊列中全部命令執行完畢。app
那麼不支持回滾對 Redis 來講有何優點:不須要支持回滾,Redis 內部能夠保證簡單而快速。函數
不支持回滾是否合理:合理,事務隊列中的命令在執行過程當中,只會由於命令錯誤的語法而失敗,而失敗的命令是編程形成的,這些錯誤應該在開發過程當中被發現,而不該該出如今生產環境中。操作系統
2). 一致性:數據庫在事務執行以前是一致的,在事務執行後不管事務執行成功仍是失敗,數據庫都應該是一致的。設計
「一致」 指的是數據符合數據庫自己的定義和要求,沒有非法或者無效的錯誤數據。Redis 經過謹慎的錯誤檢測和簡單的設計保證事務的一致性(詳看本頁:四)3d
3). 隔離性:各個事務之間不會相互影響,在併發狀態下和在串行狀態下執行事務的結果徹底相同。 blog
4). 持久性:當事務執行完畢後,結果保存到數據庫中不會丟失。
3、相關命令的用法
1). MULTI 與 EXEC:MULTI 用於開啓事務,老是返回 ok。MULTI 執行後,後面的命令暫時不會執行,而是會存到隊列中,等到 EXEC 執行以後,隊列中的命令纔會依次序執行。例子以下:
2). DISCARD 始終返回 ok,會清空事務隊列,而且放棄執行事務。例子以下:
3). WATCH 命令(想看本頁:五)
4、Redis 怎樣處理事務中的錯誤
Redis 怎樣處理事務中的錯誤來保證數據庫的 「一致性」 :
1). 入隊錯誤
可能緣由:命令不存在,命令格式不正確等
處理方式:Redis 會對入隊失敗的命令進行記錄,當調用 exec 的時候,自動拒絕執行並放棄這個事務。
例子以下:INCR mykey 1 入隊失敗,由於命令格式不正確。
2). 執行錯誤
可能緣由:命令語法錯誤(入隊時沒法檢測,只有在執行的時候纔會報錯,好比事務中處理集合的命令用在了字符串上面)。
處理方式:事務中的命令執行失敗,繼續執行下一條命令,直至事務隊列中的命令執行結束。
例子以下:LPOP mykey 報錯,做用於 list 類型,不能用於字符串;可是不影響後續命令執行,+1 操做依然執行成功。
3). 服務器停機
綜上所述,服務器停機不會影響數據庫一致性。
5、WATCH 命令與樂觀鎖
WATCH 命令的返回值老是爲 ok。
WATCH 命令自己就是一個樂觀鎖,它能夠在 EXEC 命令執行以前,監視必定數量的 key,並在 EXEC 執行時,檢查這些 key 是否被修改過,若是是的話,服務器就拒絕執行事務。例子以下:
時間 | 客戶端A | 客戶端B |
T1 | WATCH name | |
T2 | MULTI | |
T3 | SET name aa | |
T4 | SET name bb | |
T5 | EXEC |
客戶端 A 執行事務的時候發現 name 的值被修改了,因此服務器拒絕執行這個事務。
如何取消對 key 的監視: