discard:取消事務,放棄執行事務塊內的所有命令。如果正在使用 WATCH 命令監視某個(或某些) key,那么取消所有監視,等同于執行命令 UNWATCH
watch:監視一個(或多個) key ,如果在事務執行之前這個(或這些) key 被其他命令所改動,那么事務將被打斷,watch不會開啟事務。
unwatch:取消 WATCH 命令對所有 key 的監視。如果在執行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被執行了的話,那么就不需要再執行 UNWATCH 了。因為 EXEC 命令會執行事務,因此 WATCH 命令的效果已經產生了;而 DISCARD 命令在取消事務的同時也會取消所有對 key 的監視,因此這兩個命令執行之后,就沒有必要執行 UNWATCH 了。
[plain] view plain copy PRint?二、代碼實例
[java] view%20plain copy print?1.當事務執行t.exec()的時候,事務內的命令才會連續執行,并且中間不會插入其它client的命令。2.一個Redis的jedis 只能開啟一個事務,開啟多個會拋異常。3.watch操作并不一定非要在事務內操作,也可以在事物外進行watch。redis只能保證事務的每個命令連續執行,但是如果事務中的一個命令失敗了,并不回滾其他命令,比如使用的命令類型不匹配。當事務的執行過程中,如果redis意外的掛了。很遺憾只有部分命令執行了,后面的也就被丟棄了。當然如果我們使用的append-only file方式持久化,redis會用單個write操作寫入整個事務內容。即是是這種方式還是有可能只部分寫入了事務到磁盤。發生部分寫入事務的情況下,redis重啟時會檢測到這種情況,然后失敗退出??梢允褂胷edis-check-aof工具進行修復,修復會刪除部分寫入的事務內容。修復完后就能夠重新啟動了。參考:http://blog.csdn.net/freebird_lb/article/details/7734008
三、總結
1.redis事物實現,multi開始,所有指令會被放入到隊列中。當調用exec后,隊列中所有指令會依次被執行。2.multi-exec中指令執行時,所有指令只要語法合理都會被寫入隊列中。隊列執行時,指令有可能會執行失敗,但不影響其它指令執行。3.redis事物提供了樂觀鎖,通過watch指令可以實現CAS操作。watch–multi–exec操作在給key加上樂觀鎖后,當在執行exec指令前,有其它client修改此key,此事物將執行失敗。從而保證原子操作。說明:對于redis事物的應用其實需要靈活使用,上面介紹的例子是從官網翻譯而來。其實在實際中可以通過watch一些標記位來保證多線程下緩存與數據庫數據庫的一致性。(我們的系統是分布式緩存與數據庫的結合使用,緩存需要跟據數據庫的一致性很重要,下面舉例我們應用中的一個場景:)如一個service方法,serviceA,執行DAO方法(1),然后更新緩存(2),兩個并發線程,線程一執行了方法1,此刻他需要把DAO相關的數據更新到緩存2中,多線程情況下,線程二在線程一執行1后,也同樣執行1,2相關的操作,并且比線程一優先完成,這樣將導致線程一在執行2時,將出現緩存數據與數據庫不一致的現象。(以上是針對單帳號的多并發操作,發生的概率還是存在),對于以上問題我們的解決方案是:1. 帳號為acc,為每個acc在緩存中增加一個tag標識.2. 當線程一執行方法1前,設置標記位tag.3. 當執行方法2時,將會watch tag,并且比較tag是否發生了修改,如果一旦發生修改,則此次緩存操作不將更新,并清空此acc緩存。4. 如果tag值達到預期,則提交緩存更新,在提交緩存這段時間,如果tag發生變換,則redisexec提交時,會返回null ,這樣,雖然緩存內容更新成功,但跟據返回結果,可以即時清除此acc的緩存,從而清空了緩存的臟數據。5. 通過以上事物保證了緩存數據與數據庫數據不一致性的時間很短,甚至可以忽略,因為基本上在MS級別上。6. 我們的應用在緩存數據不存在acc的情況下,會嘗試從數據庫讀取,而緩存的作用只是緩解我們系統數據庫的壓力,這樣實現,很好的達到了我們的預期效果.
參考:
1.redis事務介紹與應用
新聞熱點
疑難解答