1. 程式人生 > >Redis事務介紹(四)

Redis事務介紹(四)

前言:
在傳統的關係型資料庫中,我們都知道有事務這麼個東東存在,所謂的事務也就是應用程式中一系列嚴密的操作,所有操作必須成功完成,否則在每個操作中所作的所有更改都會被撤消,也就是事務具有原子性,一個事務中的一系列的操作要麼全部成功,要麼一個都不做。這也就是事務的四大特性,也就是我們常說的ACID

那麼在redis這個非關係型資料庫中也是存在事務的,但是redis中的事務並沒有像傳統的關係型資料庫中的要求那麼嚴格,那麼接下來就介紹redis的事務

redis事務:可以一次執行多個命令,本質是一組命令的集合。一個事務中的所有命令都會序列化,按順序地序列化執行而不會被其它命令插入,不許加塞

來自官網介紹,如果要進入事務要通過MULTI命令,但是這個命令的結果是成功的,有沒有正確的執行那就是另外一碼事了,這個就和java中的強引用是差不多個意思,,這些需要執行的命令都會入隊並不會立即執行,通過exec執行事務中的命令,discard會放棄本次事務的操作

來自官網介紹,如果要進入事務要通過MULTI命令,但是這個命令的結果是成功的,有沒有正確的執行那就是另外一碼例項,這個就和java中的強引用是差不多個意思

redis事務能幹嘛:一個佇列中,一次性、順序性、排他性的執行一系列命令

redis事務使用:

redis常用命令

redis常用命令

事務例項1:正常執行

這裡寫圖片描述
大家可以看到,通過multi開啟事務之後之後的所有命令都入隊了,並沒有立即執行,而是在執行exec命令之後執行的

事務例項2:放棄事務

這裡寫圖片描述
這裡呢所有的命令也是沒有立即執行,而是將這些命令入隊,如果你覺得這個佇列中有些命令時不要執行的,那麼通過discard命令來放棄,通過結果可以看出,放棄之後那些命令並沒有執行,如果用關係型資料庫中的術語來說,就是都回滾了

事務例項3:redis事務的一致性

這裡寫圖片描述

開啟事務之後,我在這裡故意敲錯一個命令,而後面的命令任然還在入隊,但是通過exec命令執行之後發現這些改變並沒有寫入到資料庫中。這個就像關係型資料庫中的事務的一致性,要麼一起成功,要麼一起失敗

事務例項4:事務的非一致性

這裡寫圖片描述

首先呢改變k1值為11,然後開啟事務,然後就執行命令了,最後大家看看結果,發現正確的命令執行了,而那些執行失敗的命令是沒有執行的。那麼有的人就會發現,你這個命令不是和例項3一樣的嗎?兄弟,麻煩看清楚,這裡是不一樣的,例項3中有

setget k6

但是這種命令在redis中是不存在的,這個就好比是java的執行時異常和非執行時異常一個意思。所以例項3中事務都回滾了,但是例項4中的部分成功,部分失敗。

那麼對於例項3和例項4我們可以的出的總結是:
redis對事務是部分支援的,如果是在入隊時報錯,那麼都不會執行;在非入隊時報錯,那麼成功的就會成功執行。

redis監控:鎖的介紹

在MySQL中我們都知道有行鎖和表鎖的概念,所謂的行鎖也就是把我需要改的那一行給鎖住,不讓其他的事務去修改;而表鎖就是在修改一張表的時候把整張表都鎖住,不讓其他的事務修改,所以行鎖的效率比表鎖的概念更高,那麼在redis也存在鎖的概念

  • 樂觀鎖(Optimistic Lock): 顧名思義,就是很樂觀,每次去拿資料的時候都認為別人不會修改,所以不會上鎖,但是在更新的時候會判斷一下在此期間別人有沒有去更新這個資料,可以使用版本號等機制。樂觀鎖適用於多讀的應用型別,這樣可以提高吞吐量,樂觀鎖策略:提交版本必須大於記錄當前版本才能執行更新
  • 悲觀鎖(Pessimistic Lock): 顧名思義,就是很悲觀,每次去拿資料的時候都認為別人會修改,所以每次在拿資料的時候都會上鎖,這樣別人想拿這個資料就會block直到它拿到鎖。傳統的關係型資料庫裡邊就用到了很多這種鎖機制,比如行鎖,表鎖等,讀鎖,寫鎖等,都是在做操作之前先上鎖
  • CAS(Check And Set):

監控例項:銀行卡餘額

這裡寫圖片描述

大家可以看到,我在watch銀行卡餘額時然後將餘額修改成200,在開啟事務去修改餘額,發現事務執行失敗,因為這個時候在事務執行之前餘額已經被其他人修改過了,所以事務執行失敗了。類似樂觀鎖,事務提交時,如果Key的值已被別的客戶端改變,比如某個list已被別的客戶端push/pop過了,整個事務佇列都不會被執行。通過WATCH命令在事務執行之前監控了多個Keys,倘若在WATCH之後有任何Key的值發生了變化,EXEC命令執行的事務都將被放棄,同時返回Nullmulti-bulk應答以通知呼叫者事務執行失敗

這裡寫圖片描述

在watch餘額之後發現有人修改過餘額,那麼我們就可以取消watch,也就是unwatch,然後確認沒有人去修改餘額再去watch餘額,開啟事務,對餘額操作,我們發現餘額修改成功

上面呢我們通過例項說明了redis的事務

redis事務三階段:

  1. 開啟:以MULTI開始一個事務
  2. 入隊:將多個命令入隊到事務中,接到這些命令並不會立即執行,而是放到等待執行的事務佇列裡面
  3. 執行:由EXEC命令觸發事務

redis事務三大特性:

  1. 單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端傳送來的命令請求所打斷。
  2. 沒有隔離級別的概念:佇列中的命令沒有提交之前都不會實際的被執行,因為事務提交前任何指令都不會被實際執行,也就不存在”事務內的查詢要看到事務裡的更新,在事務外查詢不能看到”這個讓人萬分頭痛的問題
  3. 不保證原子性:redis同一個事務中如果有一條命令執行失敗,其後的命令仍然會被執行,沒有回滾

redis事務的介紹到這裡就告一段落了,下一次為大家帶來redis的主從複製,讀寫分離,歡迎大家繼續閱讀