Redis數(shù)據(jù)庫高級實用特性:事務控制 |
發(fā)布時間: 2012/8/7 18:07:33 |
Redis對事務的支持目前還比較簡單。redis只能保證一個client發(fā)起的事務中的命令可以連續(xù)的執(zhí)行,而中間不會插入其他client的命令。 由于redis是單線程來處理所有client的請求的所以做到這點是很容易的。一般情況下redis在接受到一個client發(fā)來的命令后會立即處理并 返回處理結果,但是當一個client在一個連接中發(fā)出multi命令有,這個連接會進入一個事務上下文,該連接后續(xù)的命令并不是立即執(zhí)行,而是先放到一個隊列中。當從此連接受到exec命令后,redis會順序的執(zhí)行隊列中的所有命令。并將所有命令的運行結果打包到一起返回給client.然后此連接就 結束事務上下文。 1、簡單事務控制 下面可以看一個例子:
從這個例子我們可以看到2個set age命令發(fā)出后并沒執(zhí)行而是被放到了隊列中。調(diào)用exec后2個命令才被連續(xù)的執(zhí)行,最后返回的是兩條命令執(zhí)行后的結果。 2、如何取消一個事務 我們可以調(diào)用discard命令來取消一個事務,讓事務回滾。接著上面例子:
可以發(fā)現(xiàn)這次2個set age命令都沒被執(zhí)行。discard命令其實就是清空事務的命令隊列并退出事務上下文,也就是我們常說的事務回滾。 3、樂觀鎖復雜事務控制 在本小節(jié)開始前,我們有必要向讀者朋友簡單介紹一下樂觀鎖的概念,并舉例說明樂觀鎖是怎么工作的。 樂觀鎖:大多數(shù)是基于數(shù)據(jù)版本(version)的記錄機制實現(xiàn)的。何謂數(shù)據(jù)版本?即為數(shù)據(jù)增加一個版本標識,在基于數(shù)據(jù)庫表的版本解決方案中,一般是通過為數(shù)據(jù)庫表添加一個 “version”字段來實現(xiàn)讀取出數(shù)據(jù)時,將此版本號一同讀出,之后更新時,對此版本號加1。 此時,將提交數(shù)據(jù)的版本號與數(shù)據(jù)庫表對應記錄的當前版本號進行比對,如果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當前版本號,則予以更新,否則認為是過期數(shù)據(jù)。 樂觀鎖實例:假設數(shù)據(jù)庫中帳戶信息表中有一個version字段,當前值為1;而當前帳戶余額字段(balance)為$100。下面我們將用時序表的方式來為大家演示樂觀鎖的實現(xiàn)原理:
這樣,就避免了操作員B用基于version=1的舊數(shù)據(jù)修改的結果來覆蓋操作員A的操作結果的可能。 即然樂觀鎖比悲觀鎖要好很多,redis是否也支持呢?答案是支持, redis從2.1.0開始就支持樂觀鎖了,可以顯式的使用watch對某個key進行加鎖,避免悲觀鎖帶來的一系列問題。 Redis樂觀鎖實例: 假設有一個age的key,我們開2個session來對age進行賦值操作,我們來看一下結果如何。
從以上實例可以看到在 第一步,Session 1 還沒有來得及對age的值進行修改 第二步,Session 2 已經(jīng)將age的值設為30 第三步,Session 1 希望將age的值設為20,但結果一執(zhí)行返回是nil,說明執(zhí)行失敗,之后我們再取一下age的值是30,這是由于Session 1中對age加了樂觀鎖導致的。 watch命令會監(jiān)視給定的key,當exec時候如果監(jiān)視的key從調(diào)用watch后發(fā)生過變化,則整個事務會失敗。也可以調(diào)用watch多次監(jiān)視多個key.這 樣就可以對指定的key加樂觀鎖了。注意watch的key是對整個連接有效的,事務也一樣。如果連接斷開,監(jiān)視和事務都會被自動清除。當然了exec,discard,unwatch命令都會清除連接中的所有監(jiān)視。 redis的事務實現(xiàn)是如此簡單,當然會存在一些問題。第一個問題是redis只能保證事務的每個命令連續(xù)執(zhí)行,但是如果事務中的一個命令失敗了,并不回滾其他命令,比如使用的命令類型不匹配。下面將以一個實例的例子來說明這個問題:
從這個例子中可以看到,age由于是個數(shù)字,那么它可以有自增運算,但是name是個字符串,無法對其進行自增運算,所以會報錯,如果按傳統(tǒng)關系型數(shù)據(jù)庫的思路來講,整個事務都會回滾,但是我們看到redis卻是將可以執(zhí)行的命令提交了,所以這個現(xiàn)象對于習慣于關系型數(shù)據(jù)庫操作的朋友來說是很別扭的,這一點也是redis今天需要改進的地方。 本文出自:億恩科技【www.allwellnessguide.com】 |