Redis事務
阿新 • • 發佈:2017-06-24
errors 隊列 存儲介質 val car 回滾 company 開發 中斷
Redis事務
Redis通過 MULTI 、 EXEC 、 WATCH 等命令來實現事務功能。事務提供了一種將多個命令請求打包,然後一次性、按順序地執行多個命令的機制,並且在事務執行期間,服務器不會中斷事務而改去執行其他客戶端的命令請求,它會將事務中的所有命令都執行完畢,然後才去處理其他客戶端的命令請求。
1.事務的實現
下面給了一個事務的簡單例子:
127.0.0.1:6379> multi OK 127.0.0.1:6379> set "name" "wangjia06" QUEUED 127.0.0.1:6379> get "name" QUEUED 127.0.0.1:6379> set "company" "dianping" QUEUED 127.0.0.1:6379> get "company" QUEUED 127.0.0.1:6379> set age 28 QUEUED 127.0.0.1:6379> get age QUEUED 127.0.0.1:6379> exec 1) OK 2) "wangjia06" 3) OK 4) "dianping" 5) OK 6) "28"
退出一個事務可以用 MULTI 命令, 此時再執行事務會報錯:
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get "company"
QUEUED
127.0.0.1:6379> get "age"
QUEUED
127.0.0.1:6379> discard
OK
127.0.0.1:6379> exec
(error) ERR EXEC without MULTI
一個事務包括三個步驟:
- 事務開始:事務以 MULTI 開始,返回OK命令。
- 命令入隊:每個事務命令成功進入隊列後,返回 QUEUED 。
- 事務執行: EXEC 執行事務。
Redis事務內會遇到兩種錯誤:
- 隊列入隊不成功:語法錯誤,錯誤的命令名字或者一些重要的條件如OOM條件。這種客戶端會進行校驗,如果入隊成功則返回QUEUED ,否則返回錯誤。如果一個命令入隊失敗,大多數客戶端會終止該事務。
127.0.0.1:6379> get name "wangjia08" 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name "wangjia09" QUEUED 127.0.0.1:6379> get (error) ERR wrong number of arguments for ‘get‘ command 127.0.0.1:6379> get name QUEUED 127.0.0.1:6379> exec (error) EXECABORT Transaction discarded because of previous errors. 127.0.0.1:6379>
- 命令執行時報錯:如對一個String值進行列表操作。所有其他的命令會被正常執行即使在事務執行中一些命令失敗。
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set sex man
QUEUED
127.0.0.1:6379> lpop sex
QUEUED
127.0.0.1:6379> exec
1) OK
2) (error) WRONGTYPE Operation against a key holding the wrong kind of value
127.0.0.1:6379> get sex
"man"
127.0.0.1:6379>
Redis不支持事務回滾功能,原因大概有兩點:
- 一個redis命令執行失敗,一般是語法錯誤或者應該在開發階段被檢測出來,而不是在生產環境。
- redis追求簡單、速度快,所以不提供事務回滾功能.
2.WATCH命令的實現
watch 命令給redis事務提供了一個 CAS 功能。它是一個樂觀鎖,檢查被監視的健是否至少有一個已經被修改過了,如果是的話拒絕執行,並返回nil代表執行失敗。
如下面例子,在一個客戶端開啟事務前對鍵“name”進行監視,若在這個事務執行前,另一個客戶端修改了鍵“name”的值,之後事務執行後就會報nil。
127.0.0.1:6379> watch "name"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set age 10
QUEUED
127.0.0.1:6379> get "name"
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> set "name" "wangjia08"
OK
watch 命令監視多個鍵:
127.0.0.1:6379> watch "name" "age"
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> get "name"
QUEUED
127.0.0.1:6379> get "age"
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379>
127.0.0.1:6379> set "age" 11
OK
3.事務的ACID性質
- 原子性:redis事務多個操作當做一個整體來執行,要麽執行事務中的所有操作,要麽一個也不執行。
- 一致性:“一致”指的是數據符合數據庫本身的定義和要求,沒有包含非法的或無效的錯誤數據
- 入隊錯誤:服務器拒絕執行該事務。
- 執行錯誤:出錯的命令會被服務器識別出來,並進行相應的錯誤處理,不會對數據庫做任何修改,也不會對數據一致性造成影響。
- 服務器停機: RDB 、 AOF 還原數據庫狀態
- 隔離性:單線程執行事務,且服務器保證事務期間不會對事務進行中斷
- 持久性:當一個事務執行完畢時,執行這個事務所得的結果已經被保存到永久性存儲介質(比如硬盤)裏面了。Redis事務的持久性由Redis所使用的持久化模式決定(無持久化模式、 RDB 、 AOF )。Redis工作在無持久化模式下時,事務無持久性。在 AOF 模式下 appenfsync 為 no 時,事務也無持久性
Redis事務