MULTI 、EXEC 、DISCARD 和WATCH 是 Redis 事務的基礎
multi開啓一個事務,成功返回OK。
例如:程序員
127.0.0.1:6379> multi OK 127.0.0.1:6379> set name allen QUEUED 127.0.0.1:6379> set age 30 QUEUED 127.0.0.1:6379> exec 1) OK 2) OK
如例所示,開啓一個事務以後,設置一個鍵值,返回QUEUED,表明已經放入一個隊列。
exec 按照隊列依次執行。
discard 命令其實就是清空事務命令並退出事務上下文,也就是咱們常說的事務回滾。.net
127.0.0.1:6379> multi OK 127.0.0.1:6379> set name frank QUEUED 127.0.0.1:6379> set age 16 QUEUED 127.0.0.1:6379> discard OK 127.0.0.1:6379> get name "allen" 127.0.0.1:6379> get age "28"
如例所示,開啓一個事務以後,設置了兩個鍵值,可是不但願事務執行,使用命令discard,令事務回滾,輸出name鍵和age鍵,仍是原來的值,說明事務已經回滾。版本控制
若是隊列中的某一個命令執行錯誤,整個事務不會回滾!
舉例說明:incr命令可使鍵的值自增1,可是隻能針對int類型的值,字符串的值就會報錯。code
127.0.0.1:6379> multi OK 127.0.0.1:6379> incr name QUEUED 127.0.0.1:6379> incr age QUEUED 127.0.0.1:6379> exec 1) (error) ERR value is not an integer or out of range 2) (integer) 29 127.0.0.1:6379> get age "29"
由於name的值是allen,incr執行果真報了錯。可是age的值卻執行成功。整個事務並無咱們預想中的回滾!blog
watch命令會監視給定的key,當exec的時候若是監視的key從調用watch以後發生過變化,則整個事務會失敗。也能夠調用watch屢次監視多個key。這樣就能夠對指定的key加樂觀鎖了。注意watch的key是對整個鏈接有效的,事務也同樣。若是鏈接斷開,監視和事務都會被自動清除。固然,exec、discard、unwatch命令都會清除鏈接中的全部監視。其實,樂觀鎖的概念就好像咱們使用的版本控制器的概念。
打開終端1:隊列
127.0.0.1:6379> watch name OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name allen QUEUED
在終端1中,使用watch監視name鍵,而後開啓事務,設置name鍵的值爲allen。
開啓另一個終端,命名終端2:事務
127.0.0.1:6379> set name frank OK
在終端2中,將name鍵的值設置爲frank。
這時候執行終端1中的事務:字符串
127.0.0.1:6379> watch name OK 127.0.0.1:6379> multi OK 127.0.0.1:6379> set name allen QUEUED 127.0.0.1:6379> exec (nil) 127.0.0.1:6379> get name "frank"
這時候能夠看到,終端1中的事務並無執行成功,當獲取name鍵的時候,返回的是在終端2中設置的值。
這就好像版本控制器同樣,版本號爲1的文件,被A,B兩個程序員下載,A程序員作完修改後,版本號變成了2,而後提交,版本庫進行了一個判斷,提交上來的版本號大於版本庫的版本號,說明提交上來的內容是新內容,OK,完成提交。這時候,B程序員也完成了修改,版本號變成了2,他也嘗試着提交,版本庫一樣作出了一個判斷,版本庫和提交上來的版本都是2,版本庫認爲B程序員提交上來的內容已通過期,不容許提交。能夠這樣簡單的理解。get
學PHP的小螞蟻 原創博客 http://my.oschina.net/woshixiaomayi/blog博客