Reputation: 1791
How to perform these operations atomically?
def setNickName(nick):
oldNick = r.get("user:id:1:nick") # r - instance of redis.Redis()
updated = r.set("user:id:1:nick", nick) if r.hsetnx("user:ref:nick", nick, '1') else False
if updated and oldNick:
r.hdel("user:ref:nick", oldNick)
return True
return False
Upvotes: 1
Views: 4737
Reputation: 13593
Let me rewrite your code with pipeline:
def setNickName(nick):
with r.pipeline() as pipe:
while 1:
try:
pipe.watch("user:id:1:nick")
oldNick = pipe.get("user:id:1:nick") # r - instance of redis.Redis()
pipe.multi()
updated = r.set("user:id:1:nick", nick) if r.hsetnx("user:ref:nick", nick, '1') else False
pipe.execute()
if updated and oldNick:
r.hdel("user:ref:nick", oldNick)
return True
print("False")
except redis.WatchError:
continue
Upvotes: -1
Reputation: 2606
You would want to do this within a transaction using watch https://github.com/andymccurdy/redis-py/#pipelines
Upvotes: 0
Reputation: 230521
You can make a lua script and execute it with EVAL command. It will effectively make this whole procedure atomic.
Note that Redis with Lua scripting is not released yet (2.6-rc5), but it's pretty stable already.
Upvotes: 6