1. 程式人生 > >複習電商筆記-28-Redis高階中的set結構和redis事務

複習電商筆記-28-Redis高階中的set結構和redis事務

 

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                #取消監控