Redis入門(六)——Redis事務mysql
目錄:redis
1.redis事務簡介sql
事務指的是能夠一次執行多個命令,本質是一組命令集合,一個事務中的全部命令都會序列化,按順序的串行化執行而不會被其餘命令插入。銀行轉帳就是最經典的事務場景之一。數據庫
redis事務用於一個隊列中,一次性,順序性。排他性的執行一系列命令。服務器
傳統的關係型數據庫如mysql,oracle中的事務須要知足ACID四個特性。即:網絡
原子性(atomicity):事務是數據庫的邏輯工做單位,並且是必須是原子工做單位,對於其數據修改,要麼所有執行,要麼所有不執行。
一致性(consistency):事務在完成時,必須是全部的數據都保持一致狀態。在相關數據庫中,全部規則都必須應用於事務的修改,以保持全部數據的完整性。
隔離性(isolation):一個事務的執行不能被其餘事務所影響。oracle
持久性(durability):一個事務一旦提交,事物的操做便永久性的保存在DB中。即使是在數據庫系統遇到故障的狀況下也不會丟失提交事務的操做。
分佈式
而redis數據屬於典型的Nosql數據庫。不須要知足ACID四個特性。Nosql數據庫知足CAP三個特性其中之二。CAP即:atom
強一致性(Consistency):在任意時刻,全部的分佈式節點中的數據是同樣的。spa
可用性(Availability):分佈式系統中某一個服務在某臺或者多臺臺服務器出問題後,在其餘服務器上依然可以完成用戶的操做。
分區容錯性(Partition torerance):在出現網絡分區(好比斷網)的狀況下,分離的系統也能正常運行。
2.redis事務使用
下表列出了 redis 事務的相關命令:
命令 | 描述 | 用法 |
MULTI | 標記一個事務塊的開始 | MULTI 標記一個事務開始,後面是一系列事務操做。 |
EXEC | 執行全部事務塊內的命令 | EXEC 在一系列事務操做後使用該命令,執行全部事務塊內的命令。 |
DISCARD | 取消事務,放棄執行事務塊內的全部命令 | DISCARD 在一系列事務操做後使用該命令,放棄執行事務塊內的全部命令 |
WATCH | 監視一個(或多個) key ,若是在事務執行以前這個(或這些) key 被其餘命令所改動,那麼事務將被打斷。 | WATCH key [key ...] |
UNWATCH | 取消 WATCH 命令對全部 key 的監視。 | UNWATCH |
MULTI命令實例:
只要符合redis語法規範的命令都可入隊。
放棄事務實例:
事務執行失敗實例:
當事務中有一個命令執行失敗,其餘命令會執行成功嗎?下圖爲實際操做的實例:
可見,redis事務中要麼所有執行成功,要麼所有執行失敗。但是前文不是說不知足原子性嗎,這裏豈不是知足原子性。上圖中出現了我胡亂加的一個命令abc k7 v7,也就是說該命令不知足redis語法規範。那若是是知足redis語法規範的語句,在redis事務中執行失敗,其餘合法命令會怎麼樣呢?下圖演示了該場景下的操做狀況。
其中,k1是一個string類型的數據,執行incr命令會不經過,可是因爲符合語法規範,該語句不會報錯,仍然顯示加入隊列中。當咱們執行EXEC命令來執行整個事務的時候後,可見incr k1執行失敗,而其餘能夠執行的語句並不受影響。可見redis事務不知足原子性。
WATCH監控:
在介紹WATCH命令以前先說明下redis中的樂觀鎖悲觀鎖的概念以及CAS。
悲觀鎖:每次器拿數據的時候都認爲該數據會被修改,因此每次拿到數據後都會對該數據上鎖,保證自由本身操做該數據。等本次獲取的鎖釋放後其餘操做方可得到該鎖。
樂觀鎖:每次器拿數據的時候都認爲該數據不會被修改,因此不會上鎖,可是下更新該數據的時候回判斷下別人有沒有更新該數據,一般使用版本號的機制。即每次修改數據後對該數據價格版本號,其餘人在修改該數據前先對比下該數據的版本號有沒有變化。通常實際場景中使用的是樂觀鎖。
下面以信用卡可用餘額與欠額的場景說明WATCH的應用。
首先來看沒有加塞的場景,WATCH balance,而後在一個事務中減小balance增長debt,執行EXEC命令後,可見事務執行成功。
再來看有加塞的場景,首先仍是WATCH balance,而後另外開啓一個redis鏈接。修改balance的值,再回到第一個redis鏈接上,執行以前的事務操做,該事務操做是否會執行成功,請看下面的操做實例
UNWATCH命令:
執行UNWATCH,取消 WATCH 命令對全部 key 的監控。注意,一旦執行了EXEC命令,以前加的監控鎖都會被取消。
3.小結
WATCH指令相似於樂觀鎖,事務提交時,若是key的值已經被別的客戶改變,好比某個list已被別的客戶端push/pop過了,整個事務都不會被執行。
經過WATCH命令在事務執行以前監控了多個key,假若在WATCH以後有任何key的值發生變化,EXEC命令執行的事務都將被放棄,同時返回Nullmuti-bulk應答已通知調用者事務執行失敗。