atomAltera
atomAltera

Reputation: 1791

Atomic operations in Redis

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

Answers (3)

Brian
Brian

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

Justin Fay
Justin Fay

Reputation: 2606

You would want to do this within a transaction using watch https://github.com/andymccurdy/redis-py/#pipelines

Upvotes: 0

Sergio Tulentsev
Sergio Tulentsev

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

Related Questions