国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

php - 使用Redis HASH的VALUE存放了一段JSON字符串,在并發(fā)操作時怎么保證JSON字符串的原子性
PHPz
PHPz 2017-04-10 16:52:45
0
2
801

假設(shè)我在Redis中存放了這樣一條HASH

HSET player Mike  "{\"height\":180,\"isAlive\":true}"

接著假設(shè)php中有2個并發(fā)操作,都是HGET這段json,json_decode成php數(shù)組.
然后對其中某個value進(jìn)行操作.json_encode后再HSET回去.

比如
一個操作將isAlive設(shè)置成false,
另一個操作是將height改成181,
那么這下很可能發(fā)生意外情況-----第二個操作在前一個操作將數(shù)據(jù)HSET到數(shù)據(jù)庫之前將數(shù)據(jù)HGET了去
哦..這下糟糕了
本來前一個操作已經(jīng)將人給弄死了,結(jié)果后一個操作又將人復(fù)活了..

然后,試想一下更多并發(fā)操作更多的VALUE...

有沒有什么好辦法能保證這段JSON的原子性呢?

PHPz
PHPz

學(xué)習(xí)是最好的投資!

reply all(2)
迷茫

你說的問題的確存在,你這里涉及到的問題其實就是普遍的讀-改-寫,redis可以保證每個操作的原子性,但是無法保證多個操作的原子性,解決的方法可以使用redis提供的multi和watch命令,具體使用如下:
1.watch住你想要讀取的key
2.multi開啟事務(wù)
3.讀取key的內(nèi)容
4.修改value內(nèi)容
5.更新key內(nèi)容
6.exec提交事務(wù),如果在2-6之間發(fā)生key的value發(fā)生了變化,那么會報錯。


以上所說只是redis能夠提供的最大的原子性操作,但是對于你的問題是沒有任何幫助的,因為在事務(wù)中執(zhí)行的命令只有等到事務(wù)提交之后才能獲取返回值,但是你的更改需要基于前一步的結(jié)果進(jìn)行操作,那么事務(wù)不提交你也就無法獲取到原來的內(nèi)容,所以無法更新。
解決辦法是把json格式字符串使用redis的hash結(jié)構(gòu)進(jìn)行保存,更新的時候直接更新hash下的一個key即可,這樣也就不會出現(xiàn)并發(fā)了,但是如果你還是需要基于原始的值進(jìn)行判斷然后再修改,那么問題還是跟上面說的一樣,沒有任何變化。

劉奇

redis是單線程模型,不用擔(dān)心這個問題

hget和hset兩個操作可以用事務(wù)控制

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template