相信phper都或多或少知道事務(wù),在一些場(chǎng)景中也會(huì)經(jīng)常用到事務(wù)。比如購(gòu)買了一個(gè)產(chǎn)品,需要向訂單表插入一條數(shù)據(jù),還要修改用戶表的余額字段等等。這兩個(gè)操作必須是要么一起成功,要么都失敗,否則就會(huì)產(chǎn)生數(shù)據(jù)不一致的情況。
Redis中也支持事務(wù)的特性。雖然沒(méi)有傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)的事務(wù)功能那樣強(qiáng)大,但它的使用非常簡(jiǎn)單。
事務(wù)
MULTI
multi標(biāo)志個(gè)一個(gè)事務(wù)的開(kāi)始。隨后的指令將在執(zhí)行EXEC時(shí)作為一個(gè)原子執(zhí)行。
DISCARD
Discard 命令用于取消事務(wù),放棄執(zhí)行事務(wù)塊內(nèi)的所有命令。
EXEC
exec命令用于執(zhí)行所有事務(wù)塊內(nèi)的命令
介紹了上面三個(gè)命令后,我們來(lái)完成一個(gè)小功能,用戶關(guān)注:
比如A用戶關(guān)注了B,那么需要在A的關(guān)注表中添加B,此外B的粉絲表中要添加A;這兩個(gè)操作要作為一個(gè)原子來(lái)執(zhí)行的。
實(shí)現(xiàn)代碼如下:
$redis->multi() ->sadd('like:A', 'B') ->sadd('fans:B', 'A') ->exec();
是不是使用起來(lái)非常簡(jiǎn)單。
樂(lè)觀鎖
首先來(lái)介紹下什么是樂(lè)觀鎖,以及它對(duì)應(yīng)的悲觀鎖。
悲觀鎖:想法很悲觀啦,對(duì)自己的男朋友不放心,只要自己和男朋友在一起時(shí),任何人都接觸不了他男朋友。Mysql中的行鎖、表鎖等,都屬于悲觀鎖。
樂(lè)觀鎖:很樂(lè)觀很天真,對(duì)自己的男朋友放心,自己和男朋友在一起時(shí),有其他朋友找她男朋友聊天時(shí),她不會(huì)阻止。但每次兩人在一起時(shí),她都會(huì)對(duì)男朋友的最近狀態(tài)做評(píng)定,判斷他是否有問(wèn)題。沒(méi)有問(wèn)題才會(huì)繼續(xù)和他在一起,否則就拜拜。
下面有一個(gè)場(chǎng)景:Redis存放著token,但是這個(gè)token是要隔一段時(shí)間就需要更新的。悲觀鎖的作為是,修改前我就要將它鎖定,這個(gè)時(shí)候其他任何請(qǐng)求都不能修改他,直到我修改完成后,才會(huì)解除鎖定。樂(lè)觀鎖的作法則是,修改的時(shí)候不會(huì)鎖定,但修改前我會(huì)觀察它的狀態(tài),如果他沒(méi)有被修改,那么我就做修改,如果狀態(tài)改變了,那么我就不做修改的操作。、
Redis中如何使用樂(lè)觀鎖的呢?
Redis中提供了一個(gè)命令Watch,標(biāo)記所有指定的key 被監(jiān)視起來(lái),在事務(wù)中有條件的執(zhí)行。
下面是偽代碼:
$redis->watch('token'); $redis->multi() ->set('token','sfwefawfwefa323') ->exec();
樂(lè)觀鎖和悲觀鎖都有自己的使用場(chǎng)景,大家可以自行查閱相關(guān)信息,這里就不多贅述了。