指可以一次執行多個命令,本質是一組命令的集合。
一個事務中的所有命令都會序列化,按順序的序列化執行而不會被其他命令插入,不許加塞。
即:一個佇列中,一次性、順序性、排他性的執行一系列命令。
我覺得最關鍵的一個不同就是redis事務不能保證原子性,在MySQL的一個事務裡的命令要麼全部成功要麼全部失敗,
但是在redis事務裡,它只會把這個事務裡的一系列命令執行完,不管成功與否,事務都算結束了。
輸入MULTI命令標記開啟一個事務,之後的每條命令都會進入對列,顯示QUEUED即已經進入佇列。
輸入EXEC命令,會執行事務塊內(佇列)的所有命令。
在事務塊內輸入命令DISCARD,該事務塊內的所有命令不會執行,並且退出該事務塊。
執行前異常一般是這種命令出錯(編譯錯誤)的異常
執行後異常一般指執行錯誤的異常,這種異常,除了出錯的命令外,正常執行的命令都會在這個事務塊執行後成功執行。不能保證原子性的原因。
1)加監控且沒有被篡改的情況:
2)加監控出現加塞篡改的情況:
watch命令是一種樂觀鎖的實現,Redis在修改的時候會檢測資料是否被更改,如果更改了,則執行失敗
第一個視窗藍色框第5步執行結果返回為空,也就是相當於是失敗,整個事務的命令都不會成功執行,相當於DISCARD
悲觀鎖(Pessimistic Lock), 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。
樂觀鎖(Optimistic Lock), 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料。
樂觀鎖策略:提交版本必須大於記錄當前版本才能執行更新
redis是效能優先的資料庫,肯定是使用的樂觀鎖實現,因為悲觀鎖實現會頻繁加鎖,對效能的消耗大。
3)unwatch:
開啟unwatch後,在該命令之前的監控全部失效,不會對資料進行監控
4)注意:
一旦執行了EXEC,之前加的監控鎖都會被取消掉;當用戶端連線斷開時,所有監控鎖會被取消。
Redis是一種基於使用者端-伺服器端模型以及請求/響應協定的TCP服務。一個請求會遵循以下步驟:
1) 使用者端向伺服器端傳送命令分四步(傳送命令→命令排隊→命令執行→返回結果),並監聽Socket返回,通常以阻塞模式等待伺服器端響應。
2) 伺服器端處理命令,並將結果返回給使用者端。
上述兩步稱為:Round Trip Time(簡稱RTT,封包往返於兩端的時間)
如果同時需要執行大量的命令,那麼就要等待上一條命令應答後再執行,這中間不僅僅多了RTT(Round Time Trip),而且還頻繁呼叫系統IO,傳送網路請求,同時需要redis呼叫多次read()和write()系統方法,系統方法會將資料從使用者態轉移到核心態,這樣就會對程序上下文有比較大的影響了,效能不太好,o(╥﹏╥)o
管道是為了解決命令往返過於頻繁而導致的RTT時長過長,僅僅是將命令打包一次性傳送,對整個redis的執行不造成其他任何影響。
它屬於批次處理命令變種優化措施,類似redis的原生批次處理命令(mset和mget),但是這種批次處理命令(例如mset)只能對string型別的資料批次處理,
如果需要對多種型別資料批次處理,就必須使用管道了
所以,管道的出現能對頻繁的命令往返進行優化,從而提升redis的效能。
這時候再去查詢資料庫會發現,這些命令都被成功且正確的執行了
管道緩衝的指令只是會依次執行,不保證原子性,如果執行過程中指令發生異常,將會繼續執行後續的指令。
使用管道組裝的命令個數也不能太多,不然資料量過大,使用者端阻塞的時間可能過久,同時伺服器端此時也被迫回覆一個佇列答覆,佔用很多記憶體。