redis 解决秒杀
#
import redis pool = redis.ConnectionPool(host = '127.0.0.1', port=6379, db=0)#创建连接池 r = redis.Redis(connection_pool = pool) # 初始化 redis pipe = r.pipeline() #初始化管道 KEY = 'count' try: pipe.watch(KEY) # 监听库存 pipe.multi() # 开始事务 pipe.set(KEY, 2) # 执行操作 pipe.execute() # 执行事务 except Exception as e: # 事务执行过程中,如果数据被修改,则抛出异常,程序可以选择重试或退出 pass finally: pipe.reset() # 重置管道,为重试做准备
import redis from threading import Thread # 创建连接池 pool = redis.ConnectionPool(host = '127.0.0.1', port=6379, db=0) # 初始化 redis r = redis.Redis(connection_pool = pool) KEY="count" # 库存 key class BaseThread(Thread): # 封装异步多线程工具 def __init__(self, func, *args, **kwargs): super(BaseThread, self).__init__() self.func = func self._args = args self._kwargs = kwargs def run(self): self.func(*self._args, **self._kwargs) def sell(i): #售卖方法 i 用户 with r.pipeline() as pipe: # 初始化 pipe while 1: try: pipe.watch(KEY) # 监听库存 c = int(pipe.get(KEY)) # 查看当前库存 if c > 0: # 有库存则售卖 pipe.multi() # 开始事务 c -= 1 pipe.set(KEY, c) # 减少库存 pipe.execute() # 执行事务 # 抢购成功并结束 print('用户 {} 抢购成功,商品剩余 {}'.format(i, c)) break else: # 库存卖完,抢购结束 print('用户 {} 抢购停止,商品卖完'.format(i)) break except Exception as e: # 抢购失败,重试 print('用户 {} 抢购失败,重试一次'.format(i)) continue finally: # 重置 pipe,准备下次抢购 pipe.reset() if __name__ == "__main__": r.set(KEY, 10) # 初始化 10 个库存 for i in range(15): # 共 15 个人开始抢购 t = BaseThread(sell, i) t.start()