开发者社区> 问答> 正文

关于 使用Redis HASH的VALUE存放了一段JSON字符串,在并发操作时怎么保证JSON字符串的原子性 问题

假设我在Redis中存放了这样一条HASH

HSET player Mike "{\"height\":180,\"isAlive\":true}"
接着假设php中有2个并发操作,都是HGET这段json,json_decode成php数组.
然后对其中某个value进行操作.json_encode后再HSET回去.

比如
一个操作将isAlive设置成false,
另一个操作是将height改成181,
那么这下很可能发生意外情况-----第二个操作在前一个操作将数据HSET到数据库之前将数据HGET了去
哦..这下糟糕了
本来前一个操作已经将人给弄死了,结果后一个操作又将人复活了..

然后,试想一下更多并发操作更多的VALUE...

有没有什么好办法能保证这段JSON的原子性呢?

展开
收起
爵霸 2016-03-05 08:30:46 4308 0
1 条回答
写回答
取消 提交回答
  • 你说的问题的确存在,你这里涉及到的问题其实就是普遍的读-改-写,redis可以保证每个操作的原子性,但是无法保证多个操作的原子性,解决的方法可以使用redis提供的multi和watch命令,具体使用如下:
    1.watch住你想要读取的key
    2.multi开启事务
    3.读取key的内容
    4.修改value内容
    5.更新key内容
    6.exec提交事务,如果在2-6之间发生key的value发生了变化,那么会报错。

    以上所说只是redis能够提供的最大的原子性操作,但是对于你的问题是没有任何帮助的,因为在事务中执行的命令只有等到事务提交之后才能获取返回值,但是你的更改需要基于前一步的结果进行操作,那么事务不提交你也就无法获取到原来的内容,所以无法更新。
    解决办法是把json格式字符串使用redis的hash结构进行保存,更新的时候直接更新hash下的一个key即可,这样也就不会出现并发了,但是如果你还是需要基于原始的值进行判断然后再修改,那么问题还是跟上面说的一样,没有任何变化。

    2019-07-17 18:52:50
    赞同 展开评论 打赏
问答排行榜
最热
最新

相关电子书

更多
Redis集群演化的心路历程——从2.x到3.0时代 立即下载
微博的Redis定制之路 立即下载
云数据库Redis版的开源之路 立即下载