1 什麼是Redis事務
Redis通過MULTI、EXEC、DISCARD以及WATCH命令提供事務功能。Redis的事務提供一次性、按順序執行命令的機制,並且不會中斷事務去執行其他命令。Redis事務和我們常理解的事務還是有些區別的,即事務中的部分命令執行失敗不會導致交易回復。Redis事務的核心思想是維護一個事務命令隊列,將事務中的所有命令先預存到隊列中,等待EXEC一起執行或者DISCARD清空隊列。 2 Redis事務命令
事務的執行分為三個步驟,事務開始、命令入隊列以及事務執行。 2.1 MULTI(事務開始)
當Redis伺服器接收到某個用戶端發送過來的MULTI命令後就會將這個用戶端的狀態標誌為事務狀態(REDIS_MULTI),事務狀態的用戶端會將除了MULTI、EXEC、DISCARD以及WATCH命令都加入到命令隊列中。如果有錯誤命令,會導致事務取消。例如:
127.0.0.1:6379> MULTIOK127.0.0.1:6379> set name "shi ke"QUEUED127.0.0.1:6379> set firstName "shi"QUEUED127.0.0.1:6379> err set(error) ERR unknown command 'err'127.0.0.1:6379> get nameQUEUED127.0.0.1:6379> get firstNameQUEUED127.0.0.1:6379> exec(error) EXECABORT Transaction discarded because of previous errors.
2.2 EXEC (事務執行)
當Redis伺服器接收到用戶端的EXEC命令後會遍曆這個伺服器的所有事務命令並且依次執行,返回結果,將用戶端狀態改回非事務。需要注意的是Redis伺服器不保證每個命令都能執行成功,已經執行成功的會改變資料庫庫狀態,不提供復原功能。 2.3 DISCARD (事務取消)
當Redis伺服器收到DISCARD命令後會清空該用戶端的事務命令隊列並且將用戶端狀態修改成非事務。例如:
127.0.0.1:6379> MULTIOK127.0.0.1:6379> set name "keshi"QUEUED127.0.0.1:6379> DISCARDOK127.0.0.1:6379> EXEC(error) ERR EXEC without MULTI
2.4 WATCH (監控)
在事務開始之前可以用WATCH命令監控特定的鍵,當有其他用戶端修改了監控的鍵,那麼伺服器將拒絕執行這個用戶端接下來的一個事務。例如:
redis-cli-1 redis-cli-2127.0.0.1:6379> WATCH nameOK127.0.0.1:6379> MULTIOK127.0.0.1:6379> get nameQUEUED127.0.0.1:6379> set firstName "Yang" 127.0.0.1:6379> set name "Yang Li"QUEUED127.0.0.1:6379> EXEC(nil)127.0.0.1:6379> get firstName"shike"127.0.0.1:6379> get name"Yang Li"
3 Redis事務的ACID原則
事務的ACID即事務的原子性、一致性、隔離性、持久性,Redis事務能夠保證原子性、一致性、隔離性但是不會保證持久性。 3.1 原子性
事務的原子性是指一組操作要麼全部執行,要麼全不執行。Redis可以保證一組資料同時執行或者不執行。但是不同於MySQL等關聯式資料庫事務操作,Redis不提供復原操作即部分操作失敗不會引起整個交易回復。 3.2 一致性
事務的一致性指資料庫中的資料全部符合資料庫的規範,不會出現不符合規範的資料存在。Redis通過嚴格的錯誤偵測保證事務的一致性。
第一、入隊時的錯誤回直接導致整個事務失敗,保證一致性。
第二、執行時錯誤會跳過錯誤命令,繼續執行其他命令。
第三、伺服器重啟,如果有持久化則通過RDB、AOF檔案恢複資料,否則資料庫為空白。 3.3 隔離性
Redis事務在執行之前只是將命令存在操作隊列中,不會真正去操作資料庫,所有事務之間不會相互影響。 3.4 持久性
Redis事務是否具有持久性是由他的持久化策略決定的,若且唯若採用AOF模式並且appendfsync設為always時才具有持久性,具體原因請看Redis持久化介紹(http://blog.csdn.net/sk199048/article/details/50589491)