想了很久,實在不能理解代碼清單6-9中鎖的使用原理,鎖只是設(shè)置了一個key,而且完全沒有用到(比如if getkey()==true之類的),生成的鎖還是隨機的,也就是不還是沒解決并發(fā)的問題嗎? 同一時間仍然有可能會有其他客戶端對數(shù)據(jù)進行操作。求大佬解惑,謝謝。
# 代碼清單 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:
# 檢查物品是否已經(jīng)售出,以及買家是否有足夠的金錢來購買物品。
pipe.zscore("market:", item)
pipe.hget(buyer, 'funds')
price, funds = pipe.execute()
if price is None or price > funds:
return None
# 將買家支付的貨款轉(zhuǎn)移給賣家,并將售出的物品轉(zhuǎn)移給買家。
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
# 進程已經(jīng)失去了鎖。
return False
# <end id="_1314_14473_8650"/>
添加回答
舉報
0/150
提交
取消