1. 程式人生 > >分散式快取redis之事務

分散式快取redis之事務

關係型資料庫的事務具備:原子性(A)、一致性(C)、隔離性(I)、永續性(D)。在redis中也同樣擁有事務的概念

redis事務的使用

redis中與事務相關的命令有5個,分別是:MULTI EXEC DISCARD WATCH UNWATCH

1)MULTI命令用於開啟事務

開啟事務後,可以開始對鍵執行操作,能看到開啟事務後命令的返回都是”QUEUED”,Redis Server收到這些命令後將他們儲存在佇列中,只有收到EXEC命令才會真正執行。


2)EXEC命令:當在exec之前使用watch命令的話,只有被watch的key沒有被修改的情況下,exec命令才真正執行,exec的返回結果是一個Array結構的資料,其中每個元素是事務中順序執行的命令的結果

3)當執行了MULTI命令和一些操作後,想放棄當前事務,可以使用DISCARD命令,DISCARD命令會清空事務命令佇列,並退出事務(注意discard並不是rollback回滾)。

4)watch命令:監控一個或者多個key,如果這些key在提交事務exec之前被其他使用者修改過,那麼事務執行失敗,需要重新獲取最新資料從頭操作,使得redis事務具有check-and-set語義,watch命令如下:


上述命令中:Client1對count使用WATCH命令後開啟事務,在執行EXEC命令前,Client2修改了count的值,Client1執行EXEC命令會失敗。

5)unwatch:取消WATCH命令對所有key的監控,所有監控鎖將會被取消。

redis事務的特性

1;單獨的隔離操作:事務中的所有命令會被序列化、按順序執行,在執行的過程中不會被其他客戶端傳送來的命令打斷

2:沒有隔離級別的概念:佇列中的命令在事務沒有被提交之前不會被實際執行

3: 不保證原子性:redis中的一個事務中如果存在命令執行失敗,那麼其他命令依然會被執行(比如出現下面的錯誤型別二),沒有回滾機制


在第五條命令中我隨便打了幾個字元,提交事務的時候並沒有成功,這也很符合我們對事務的理解。從圖中可以看到錯誤命令在我輸入的時候就已經報錯了,也就是說這條錯誤命令在進入佇列的時候redis就已經知道這是一條錯誤命令,這樣,整個事務的命令將全部失敗,那麼,有沒有一種可能某個錯誤指令在進入佇列的時候redis還沒有發現他的錯誤呢?比如:



這就是我們上面提到的第二類錯誤,對於一個存在問題的命令,如果在入隊的時候就已經知道其出錯,整個事務內的命令將都不會被執行(其後續的命令依然可以入隊),如果這個錯誤命令在入隊的時候並沒有報錯,而是在執行的時候出錯了,那麼redis預設跳過這個命令執行後續命令。也就是說,redis只實現了部分事務(並不能保證事務的原子性)