一、Redis事務
Redis 提供的事務機制與傳統的數據庫事務有些不同,傳統數據庫事務必須維護以下特性:原子性(Atomicity), 一致性(Consistency),隔離性(Isolation),持久性(Durability),簡稱ACID。
Redis支持簡單的事務,將執行命令放入隊列緩存,程序中有異常,執行discard回滾,其實只是取消隊列命令的執行。但執行exec時,已經執行的命令,是無法回滾的。
但是Redis 的應用場景明顯不是為了數據存儲的高可靠而設計的,而是為了數據訪問的高性能而設計,設計者為了簡單性和高性能而部分放棄了原子性。
Redis的事務中,啟用的是樂觀鎖,使用watch命令負責監控key有沒有被改動過,在事務中,如果任意一個監控的key有改變,則事務取消。
Redis與 mysql事務的對比:
Mysql | redis | |
開啟事務 | start transaction | multi |
執行語句 | 普通sql (建表語句會立即執行) | 普通redis命令 |
失敗 | rollback 回滾 | discard 取消 |
成功 | commit | exec |
1、模擬一個redis事務操作過程
批量操作在發送 exec 命令前被放入隊列緩存,收到 exec 命令后進入事務執行
2、在mutil后面的語句中,語句出錯可能有2種情況:
① 語法有問題,在exec時會報錯, 所有語句得不到執行。
② 語法本身沒錯,但命令適用對象有問題,exec之后,會執行正確的語句,並跳過有不適當的語句。這里其實就沒有真正意義上的回滾事務,這種情況只能是開發者自己避免。
3、discard 取消事務,清空隊列即可,比較簡單。
4、redis中的樂觀鎖
准備兩個客戶端,模擬搶票,這里設置只有一張票:
zhang客戶端,准備買票,正在事務中,還沒執行最終的命令:
而此時,wang這邊已經把票買走了,票剩下0張
再看張這邊,執行命令后,票數卻剩下-1張了,這是不科學的。
所以,為了避免上面這種情況,redis中使用樂觀鎖來監控key有沒有被改動
同樣,zhang這邊准備好執行命令,但在開始事務前使用watch監控ticket的變動:
之后,王這邊買票成功,票剩余0張:
zhang這邊再執行命令:
返回nil,說明票已被改動過,事務就取消了。
使用unwatch命令取消所有watch監聽
二、消息訂閱與發布
Redis 發布訂閱(pub/sub)是一種消息通信模式,可以用於消息的傳輸,Redis的發布訂閱機制包括三個部分,發布者,訂閱者和Channel。適宜做在線聊天、消息推送等。
發布者和訂閱者都是Redis客戶端,Channel則為Redis服務器端,發布者將消息發送到某個的頻道,訂閱了這個頻道的訂閱者就能接收到這條消息,客戶端可以訂閱任意數量的頻道
1、publish channel message:發布者向指定的頻道發布消息
2、sbuscribe channel [channel2 ... n]:訂閱者訂閱某個或幾個頻道,監聽channel的消息
訂閱者訂閱頻道后,只能接收到之后發布者發布的消息
訂閱后,發布者再發布消息,可以看到有一個客戶端接收到消息了
3、psubscribe pattern [pattern2 .. n]:根據匹配模式訂閱頻道,可訂閱多個匹配的頻道
訂閱所有redis頻道
可以看到接收到匹配頻道的消息
4、pubsub channels [pattern]:列出活躍的頻道
5、pubsub subnum channel [channel2 .. n]:查詢頻道訂閱者數量