Redis example in action

From the book "Redis in Action" that I read, I saw the following example, and now I wonder if this is correct or not. The example contains the following code in python:

def purchase_item(conn, buyerid, itemid, sellerid, lprice):
buyer = "users:%s"%buyerid
seller = "users:%s"%sellerid
item = "%s.%s"%(itemid, sellerid)
inventory = "inventory:%s"%buyerid
end = time.time() + 10
pipe = conn.pipeline()


while time.time() < end:
    try:
        pipe.watch("market:", buyer)                #A
        price = pipe.zscore("market:", item)        #B
        funds = int(pipe.hget(buyer, "funds"))      #B
        if price != lprice or price > funds:        #B
            pipe.unwatch()                          #B
            return None


        pipe.multi()                                #C
        pipe.hincrby(seller, "funds", int(price))   #C
        pipe.hincrby(buyer, "funds", int(-price))   #C
        pipe.sadd(inventory, itemid)                #C
        pipe.zrem("market:", item)                  #C
        pipe.execute()                              #C
        return True
    except redis.exceptions.WatchError:             #D
        pass                                        #D


return False

As you can see, this example uses pipelining and from what I understand, the commands are not executed until pipe.execute () is called. In this example, you see the if statement in #B, but is this the price value returned here? Or, an exploit of the code is invoked somehow buffered when conn.pipeline () is called.

+4
source share
1 answer

, redis-py. pipe.watch(), . , python . , pipe.multi(), . pipe.execute() , "#C" . redis-py. :

pipe.watch(...) # <--- executed immediately
pipe.zscore(...) # <--- executed immediately
.....
pipe.multi() # <--- put pipeline back in *buffered* mode
pipe.incr(..) # <--- buffered command 1
pipe.incr(..) # <--- buffered command 2
pipe.execute() # <--- execute buffered commands 1 and 2
+9

Source: https://habr.com/ru/post/1535149/


All Articles