利用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
测试