想了很久,实在不能理解代码清单6-9中锁的使用原理,锁只是设置了一个key,而且完全没有用到(比如if getkey()==true之类的),生成的锁还是随机的,也就是不还是没解决并发的问题吗? 同一时间仍然有可能会有其他客户端对数据进行操作。求大佬解惑,谢谢。
# 代码清单 6-8
# <start id="_1314_14473_8641"/>
def acquire_lock(conn, lockname, acquire_timeout=10):
# 128位随机标识符。
identifier = str(uuid.uuid4())
end = time.time() + acquire_timeout
while time.time() < end:
# 尝试取得锁。
if conn.setnx('lock:' + lockname, identifier):
return identifier
time.sleep(.001)
return False
# <end id="_1314_14473_8641"/>
# 代码清单 6-9
# <start id="_1314_14473_8645"/>
def purchase_item_with_lock(conn, buyerid, itemid, sellerid):
buyer = "users:%s" % buyerid
seller = "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)
# <end id="_1314_14473_8645"/>
# 代码清单 6-10
# <start id="_1314_14473_8650"/>
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
# <end id="_1314_14473_8650"/>
添加回答
举报
0/150
提交
取消