Redis, 仅允许对现有键执行操作

2024-06-02 13:03:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用python包(redispy)来操作redis数据库。我有很多客户机在redis中设置哈希的键和值。我希望它们只在哈希存在时设置键和值。如果哈希不存在,设置键和值将创建哈希,这不是我想要做的。在

在redis py页面中(https://github.com/andymccurdy/redis-py)提出了一种在客户端进行原子操作的方法。所以我写了一个类似的函数:

    with r.pipeline() as pipe:
        while True:
            try:
                pipe.watch("a_hash")
                if pipe.exists("a_hash"):
                    pipe.hset("a_hash", "key", "value")                  
                break
            except redis.WatchError:
                continue
            finally:
                pipe.reset()

然而,这似乎行不通。在我从另一个客户机上删除哈希之后,这个哈希仍然由这段代码创建,所以我猜这段代码不是原子操作。有人能帮我找出这个代码有什么问题吗?还是有更好的方法来达到这个目的?在

感谢你的帮助!在


Tags: 方法代码pyhttpsgithubcomredis数据库
1条回答
网友
1楼 · 发布于 2024-06-02 13:03:02

我建议阅读WATCH/MULTI/EXEC块的定义,如Redis documentation中所述。在

在这样的块中,实际上只有MULTI和EXEC之间的命令被原子化地处理(并且有条件地,根据手表的不同,使用all或nothing语义)。在

在您的示例中,EXISTS和HSET命令不是以原子方式执行的。实际上,你不需要这种原子性:你想要的是有条件的执行。在

这应该会更好:

with r.pipeline() as pipe:
    while True:
        try:
            pipe.watch("a_hash")
            if pipe.exists("a_hash"):
                pipe.multi()
                pipe.hset("a_hash", "key", "value")
                pipe.execute()
            break
        except redis.WatchError:
            continue
        finally:
            pipe.reset()

如果密钥在EXISTS之后但在MULTI之前被删除,HSET将不会被执行,这要归功于watch。在

在Redis 2.6中,Lua server-side script可能更易于编写,而且效率更高。在

相关问题 更多 >