27

I tested all the transaction commands (MULTI, EXEC, WATCH, DISCARD) in redis-cli. But when i tried with redis-py the following error occurred:

AttributeError: 'Redis' object has no attribute 'multi'

I have tried the following code snippet:

import redis,time

r = redis.Redis()
try:
    r.set("transError",10)
    r.watch("transError")
    var = r.get("transError")
    var = int(var) + 1
    print "Run other client to simulate an error without transaction"
    time.sleep(4)
    r.multi()
    r.set("transError",var)
    r.execute()
    print "Value in first client",r.get("transError")

except redis.WatchError:
    print "Value Altered"

I have seen code example that is using multi() and execute() but they are not working for me. Any help?

frankfalse
  • 1,553
  • 1
  • 4
  • 17
Ahsanul Haque
  • 10,676
  • 4
  • 41
  • 57

1 Answers1

44

In redis-py MULTI and EXEC can only be used through a Pipeline object.

Try the following:

r = redis.Redis()
p = r.pipeline()
p.set("transError", var)
p.execute()

With the monitor command through the redis-cli you can see MULTI, SET, EXEC sent when p.execute() is called. To omit the MULTI/EXEC pair, use r.pipeline(transaction=False).

ntki
  • 2,149
  • 1
  • 16
  • 19
  • This answer looks perfect. Though I have one question: How many commands can be efficiently executed together ? is it okay if I pass 500000 commands in one pipeline OR it will be too much for redis ? – Tushar J Dudhatra Nov 01 '17 at 16:19
  • @TusharJDudhatra You really have to measure that for yourself for your individual application. In my experience though it is usually preferable to batch only a sane number of commands together... like 10000 of them. Also in redis-py the pipeline sends all commands at once when you execute it, not continuously, regardless of transaction=False. See: https://redis.io/topics/pipelining https://github.com/schlitzered/pyredis/issues/2 – ntki Nov 02 '17 at 07:43
  • 1
    Thank you for your response. Yes I tried executing 500K commands in one pipeline and it went smoothly for me. – Tushar J Dudhatra Nov 04 '17 at 14:33
  • What if I need to perform a read request? I try to atomically increment a value in a json which is stored as a string in Redis. Is it possible? Btw I cannot use RedisJSON as my vendor doesn't support it yet. – Oleg Yablokov Jan 17 '22 at 15:57
  • I found a solution: just store the value I want to increment in a different key! :) – Oleg Yablokov Jan 17 '22 at 16:19