[Python] 纯文本查看 复制代码
def acquire_lock(conn, lockname, acquire_timeout=10):
identifier = str(uuid.uuid4()) //128位随机标识符
end = time.time() + acquire_timeout
while time.time() < end:
if conn.setnx('lock:' + lockname, identifier): //尝试获取锁
return identifier
time.sleep(.001)
return False
[Python] 纯文本查看 复制代码
def purchase_item_with_lock(conn, buyerid, itemid, sellerid):
buyer = "users:%s"%buyerid
sellerid = "users:%s"%sellerid
item = "%s.%s"%(itemid, sellerid)
inventory = "inventory:%s"%buyerid
locked = acquire_lock(conn, market)
if not locked:
return False
pipe = conn.pipeline(True)
try://检查指定的商品是否仍在出售,以及买家是否有足够的钱来购买该商品
pipe.zscore("market:", item)
pipe.hget(buyer, 'funds')
price, funds = pipe.execute()
if price is None or price > funds:
return None
pipe.hincrby(seller, 'funds', int(price))
pipe.hincrby(buyer, 'funds', int(-price))
pipe.sadd(inventory, itemid)
pipe.zrem("market:", item)
pipe.execute()
return True
finally:
release_lock(conn, market, locked) //释放锁
[Python] 纯文本查看 复制代码
def release_lock(conn, lockname, identifier):
pipe = conn.pipeline(True)
lockname = 'lock:' + lockname
while True:
try:
pipe.watch(lockname)
if pipe.get(lockname) == identifier:
pipe.multi()
pipe.delete(lockname)
pipe.execute()
return True
pipe.unwatch()
break
except redis.exceptions.WatchError:
pass
return False
[Python] 纯文本查看 复制代码
def acquire_lock_with_timeout(conn, lockname, acquire_timeout=10, lock_timeout=10):
identifier = str(uuid.uuid4())
lockname = 'lock:' + lockname
lock_timeout = int(math.ceil(lock_timeout))
end = time.time() + acquire_timeout
while time.time() < end:
if conn.setnx(lockname, identifier):
conn.expire(lockname, lock_timeout)
return identifier
elif not conn.ttl(lockname):
conn.expire(lockname, lock_timeout)
time.sleep(.001)
return False