利用redis的樂觀鎖,實現秒殺系統的數據同步(基於watch實現)html
import redis conn = redis.Redis(host='127.0.0.1',port=6379) # conn.set('count',1000) with conn.pipeline() as pipe: # 先監視,本身的值沒有被修改過 conn.watch('count') # 事務開始 pipe.multi() old_count = conn.get('count') count = int(old_count) # input('我考慮一下') if count > 0: # 有庫存 pipe.set('count', count - 1) # 執行,把全部命令一次性推送過去 ret2 = pipe.execute() print(ret2) # [True] ret = pipe.execute() print(type(ret)) print(ret) # []
注:windows下若是數據被修改了,不會拋異常,只是返回結果的列表爲空,mac和linux會直接拋異常python
秒殺系統核心邏輯測試,建立100個線程併發秒殺linux
#!/usr/bin/env python # -*- coding:utf-8 -*- import redis from multiprocessing import Process from threading import Thread import random, time from redis import WatchError def miaosha(name, conn, pipe): # 先監視,本身的值沒有被修改過 # while stack_count > 0: try: pipe.watch('count') # 事務開始 pipe.multi() old_count = conn.get('count') count = int(old_count) # input('我考慮一下') # time.sleep(random.randint(1, 2)) # time.sleep(random.random()) if count > 0: # 有庫存 # set以後對應ret 爲[True]或者[], 而decr對應自減, 其ret 爲[對應的count殘餘值] pipe.set('count', count - 1) # pipe.decr("count") # 執行,把全部命令一次性推送過去 ret = pipe.execute() print(ret) if len(ret) > 0: print('第%s我的搶購成功' % name) return True else: print('第%s我的搶購失敗' % name) return True # return True except WatchError as e: # 打印WatchError異常, 觀察被watch鎖住的狀況 # print(e) # print("當前用戶搶購失敗") pipe.unwatch() return False def choose(name, conn): with conn.pipeline() as pipe: res = miaosha(name, conn, pipe) return res def worker(name, conn): for r in range(3): res = choose(name, conn) if res: break else: print(f"第{r+1}次嘗試~~~") def threading_work(): conn = redis.Redis(host='127.0.0.1', port=6379) for i in range(100): t = Thread(target=worker, args=(i, conn)) t.start() if __name__ == '__main__': # 多進程多線程本案例, 會出現打印文字重複問題, 實際操做須要調整, 應用於測試 # tt_list = [] # for r in range(4): # tt = Process(target=threading_work) # tt_list.append(tt) # tt.start() # for tt in tt_list: # tt.join() conn = redis.Redis(host='127.0.0.1', port=6379) for i in range(300): t = Thread(target=worker, args=(i, conn)) t.start()
上面列子我的網上找來參考改動挺多, 實現了對規定秒殺庫存數的完整性redis
我的代碼的實現邏輯>>>:windows
實現了貨物存在時部分用戶可購買商品成功, 部分用戶由於線程操做問題, 不能購買到貨物, 在except部分進行了對應的邏輯打印, 而在 貨物處於0 時候則報出 當前第幾用戶購買失敗的效果, 實現了我的以爲測試下沒有問題的秒殺多線程
理解後, 部分複製之併發
參考文獻地址>>>:app
https://www.cnblogs.com/wangwei916797941/p/10030882.html
dom
https://www.cnblogs.com/liuqingzheng/p/9997092.html
測試