複習電商筆記-28-Redis高階中的set結構和redis事務
阿新 • • 發佈:2018-11-17
Redis高階中的set結構
Redis的Set是string型別的無序集合。集合成員是唯一的,這就意味著集合中不能出現重複的資料。Redis中集合是通過雜湊表實現的,所以新增,刪除,查詢的複雜度都是O(1)。集合中最大的成員數為232 - 1 (4294967295每個集合可儲存40多億個成員)。
sadd
新增元素,重複元素新增失敗,返回0
127.0.0.1:6379> sadd name tony (integer) 1 127.0.0.1:6379> sadd name hellen (integer) 1 127.0.0.1:6379> sadd name rose (integer) 1 127.0.0.1:6379> sadd name rose (integer) 0
smembers
獲取內容
127.0.0.1:6379> smembers name
1) "hellen"
2) "rose"
3) "tony"
spop
移除並返回集合中的一個隨機元素
127.0.0.1:6379> smembers internet 1) "amoeba" 2) "redis" 3) "rabbitmq" 4) "nginx" 127.0.0.1:6379> spop internet "rabbitmq" 127.0.0.1:6379> spop internet "nginx" 127.0.0.1:6379> smembers internet 1) "amoeba" 2) "redis"
scard
獲取成員個數
127.0.0.1:6379> scard name
(integer) 3
smove
移動一個元素到另外一個集合
127.0.0.1:6379> sadd internet amoeba nginx redis (integer) 3 127.0.0.1:6379> sadd bigdata hadopp spark rabbitmq (integer) 3 127.0.0.1:6379> smembers internet 1) "amoeba" 2) "redis" 3) "nginx" 127.0.0.1:6379> smembers bigdata 1) "hadopp" 2) "spark" 3) "rabbitmq" 127.0.0.1:6379> smove bigdata internet rabbitmq (integer) 1 127.0.0.1:6379> smembers internet 1) "amoeba" 2) "redis" 3) "rabbitmq" 4) "nginx" 127.0.0.1:6379> smembers bigdata 1) "hadopp" 2) "spark" 127.0.0.1:6379>
sunion
並集
127.0.0.1:6379> sunion internet bigdata
1) "redis"
2) "nginx"
3) "rabbitmq"
4) "amoeba"
5) "hadopp"
6) "spark"
redis事務管理
redis是單執行緒,提交命令時,其它命令無法插入其中,輕鬆利用單執行緒實現了事務的原子性。那如果執行多個redis命令呢?自然就沒有事務保證,於是redis有下列相關的redis命令來實現事務管理。
multi 開啟事務
exec 提交事務
discard 取消事務
watch 監控,如果監控的值發生變化,則提交事務時會失敗
unwatch 去掉監控
Redis保證一個事務中的所有命令要麼都執行,要麼都不執行。如果在傳送EXEC命令前客戶端斷線了,則Redis會清空事務佇列,事務中的所有命令都不會執行。而 一旦客戶端傳送了EXEC命令,所有的命令就都會被執行,即使此後客戶端斷線也沒關係,因為Redis中已經記錄了所有要執行的命令。
exec提交事務
例如:模擬轉賬,王有200,張有700,張給王轉100。過程如下:
127.0.0.1:6379> set w 200
OK
127.0.0.1:6379> set z 700
OK
127.0.0.1:6379> mget w z
1) "200"
2) "700"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby z 100
QUEUED #注意此命令根本沒有執行,而是把其放在一個佇列中
127.0.0.1:6379> incrby w 100
QUEUED
127.0.0.1:6379> mget w z
QUEUED
127.0.0.1:6379> get w #同時,這些相關的變數也不能再讀取
QUEUED
127.0.0.1:6379> get z
QUEUED
127.0.0.1:6379> exec
1) (integer) 600
2) (integer) 300
3) 1) "300"
2) "600"
4) "300"
5) "600"
127.0.0.1:6379> mget w z
1) "300"
2) "600"
127.0.0.1:6379>
如果有錯誤命令,自動取消
127.0.0.1:6379> mget w z
1) "300"
2) "600"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get w
QUEUED
127.0.0.1:6379> set w 100
QUEUED
127.0.0.1:6379> abc
(error) ERR unknown command 'abc'
127.0.0.1:6379> exec
(error) EXECABORT Transaction discarded because of previous errors.
127.0.0.1:6379> get w
"300"
127.0.0.1:6379>
discard取消事務
注意redis事務太簡單,沒有回滾,而只有取消。
127.0.0.1:6379> mget z w
1) "600"
2) "300"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> incrby z 100
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> get z
"600"
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
秒殺
客戶端1:
127.0.0.1:6379> clear
127.0.0.1:6379> set ticket 1
OK
127.0.0.1:6379> set money 0
OK
127.0.0.1:6379> watch ticket #樂觀鎖,對值進行觀察,改變則事務失敗
OK
127.0.0.1:6379> multi #開啟事務
OK
127.0.0.1:6379> decr ticket
QUEUED
127.0.0.1:6379> incrby money 100
QUEUED
客戶端2:還沒等客戶端1提交事務,此時客戶端2把票買到了。
127.0.0.1:6379> get ticket
"1"
127.0.0.1:6379> decr ticket
(integer) 0
客戶端1:
127.0.0.1:6379> exec
(nil) #執行事務,失敗
127.0.0.1:6379> get ticket
"0"
127.0.0.1:6379> unwatch #取消監控