Redis中的Multi事務

一、概述

Redis中的Multi和Pipleline都可以一次性執行多個命令,但是Pipeline只是把多個redis指令一起發出去,redis並沒有保證這些指令執行的順序,且減少了多次網絡傳遞的開銷,因而其執行效率很高;Multi相當於一個redis的transaction,保證整個操作的有序性,通過watch這些key,可以避免這些key在事務的執行過程中被其它的命令修改,從而導致得的到結果不是所期望的。

官方介紹MULTI 、 EXEC 、 DISCARD 和 WATCH 是 Redis 事務相關的命令,事務可以一次執行多個命令,但是必須滿足2個條件:

  1.     事務是一個單獨的隔離操作:事務中的所有命令都會序列化、按順序地執行。事務在執行的過程中,不會被其他客戶端發送來的命令請求所打斷。
  2.     事務是一個原子操作:事務中的命令要麼全部被執行,要麼全部都不執行。執行和是否成功是2個概念,並不是一個失敗報錯等,其他就失敗。redis對事務是部分支持。如果最開始語法等就有提交錯誤,就相當於java的編譯器都過不了,那麼肯定全部不執行。如果在執行過程中報錯,已經全部執行了,但是誰報錯找誰,其他正常執行放行。各取所需!這裏的事務並不是要麼全部成功,要麼全部失敗,全部執行和全部成功(或者都失敗)是2個概念。

二、命令介紹

  • MULTI:開啓事務,總是返回OK
  • EXEC:提交事務
  • DISCARD:放棄事務(放棄提交執行)
  • WATCH:監控
  • QUEUED:將命令加入執行的隊列

三、示例演示

1、開啓事務

可以看到即使開了事務,事務中正確的命令也得到了執行,不正確的命令沒有被執行,誰出錯誰負責。

2、對部分命令增加watch

增加watch命令,可以確保被watch的key在事務的執行期間,如果被其它連接修改了,則當前事務則會在執行exec時報錯,事務被中斷,事務中所有的命令都不會執行。

1)對名爲t1的key增加watch

127.0.0.1:6379> watch t1
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set t1 t111
QUEUED
127.0.0.1:6379> set t2 v222
QUEUED
127.0.0.1:6379> set t3 v333
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get t1
"v111"
127.0.0.1:6379> get t2
"v2"
127.0.0.1:6379> get t3
"t33"

此時在事務的執行區間,即在執行了multi之後未執行exec之前,其它連接執行了修改t1的如下操作:

127.0.0.1:6379> set t1 v111
OK

在執行exec命令時就報了(nil)這樣一個錯誤結果,表示當前事務執行失敗。通過後續的get命令查看t1、t2和t3的值,只有t1的值發生了變化,是被其它連接修改了,當前事務中的命令都沒有被執行。

2)對名爲t2的key增加watch

127.0.0.1:6379> watch t2
OK
127.0.0.1:6379> multi
OK
127.0.0.1:6379> set t1 t111
QUEUED
127.0.0.1:6379> set t2 v222
QUEUED
127.0.0.1:6379> set t3 v333
QUEUED
127.0.0.1:6379> exec
(nil)
127.0.0.1:6379> get t1
"v111"
127.0.0.1:6379> get t2
"v222"
127.0.0.1:6379> get t3
"t33"
127.0.0.1:6379> unwatch
OK

在事務區間,其它連接對t2進行了修改:

127.0.0.1:6379> set t2 v222
OK

當執行事務提交命令exec時,發現被watch的t2被修改了,當前事務執行失敗,通過get命令查看,只有t2的值發生了變化,是被其它連接修改了的,當前事務全部命令都沒有執行。

這兩個增加對key進行watch的示例,演示了被watch的key可以是事務中的任意key,只要是被watch的key被修改,整個事務都不會執行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章