Python利用Redis键空间回调函数,30分钟未支付取消订单

业务场景:
用户下单之后,在30分钟内如果不完成付款,订单自动取消,并且释放库存

使用技术:
Redis键空间通知(过期回调)用户下单之后将订单id作为key,任意值作为值存入redis中,给这条数据设置过期时间,也就是订单超时的时间

声明:
*本人菜鸟一枚,以下代码仅记录自己学习历程,不保证代码效果及性能,如有更好的方式,也欢迎讨论.

1.开启键空间通知
默认情况下,键空间通知是关闭的,需要在终端开启
redis-cli config set notify-keyspace-events KEA
KEA 参数意味着每一个可能的事件被启用
在这里插入图片描述
2.检查事件是否正常,终端输入

redis-cli --csv psubscribe '*' 

psubscribe ‘*’ 意味着我们想要使用模式订阅所有事件
结果:

$ redis-cli --csv psubscribe '*'     
Reading messages... (press Ctrl-C to quit)  
"psubscribe","*",1

3.测试
新打开一个终端,输入

127.0.0.1:6379> set key1 value1  
OK  

在第一个终端,您将看到:

"psubscribe","*",1
"pmessage","*","__keyspace@0__:key1","set"
"pmessage","*","__keyevent@0__:set","key1

通知说明:
第一个事件意味着我们已成功订阅作为回复中第二个元素的通道。1表示我们当前订阅的频道数。
第二个事件是密钥空间通知。在密钥空间信道中,我们收到了事件的名称set作为消息。
第三个事件是关键事件通知。在keyevent频道中,我们收到了密钥的名称key1作为消息。

4.配置回调函数
a.首先在订单前,生成redis字符串,设置订单id,并有有效期
b.创建一个脚本文件,和django一起启动AutoCancelOrder.py

# 连接redis数据库
redis = StrictRedis(host='localhost', port=6379, decode_responses=True)

# 创建pubsub对象,该对象订阅一个频道并侦听新消息:
pubsub = redis.pubsub()

# 定义触发事件
def event_handler(msg):
    print('Handler', msg)
    print(msg['data'])
    order_id = str(msg['data'])

    # 获取订单对象
    order = OrderInfo.objects.get(order_id=order_id)

    # 判断用户是否已经付款
    if str(order.status) == "1":

        # 取消订单,更改订单状态
        OrderInfo.objects.filter(order_id=order_id).update(status="6")

        # 获取订单中的所有商品
        goods = order.skus.all()
		
		# 遍历商品
        for good in goods:
            
            # 获取订单中的商品数量
            count = good.count
            print(count)

            # 获取sku商品
            sku = good.sku

            # 将库存重新增加到sku的stock中去
            sku.stock += count
            
            # 从销量中减去已经取消的数量
            sku.sales -= count
            sku.save()
            
#订阅redis键空间通知
pubsub.psubscribe(**{'__keyevent@0__:expired': event_handler})

# 死循环,不停的接收订阅的通知
while True:
    message = pubsub.get_message()
    if message:
        print(message)
    else:
        time.sleep(0.01)

5.代码解释:
创建while True循环接收事件通知:

while True:
	......

keyevent@0:expired’:
设定通知类型: keyspace、keyevent
设置事件类型: expired
选中数据库号: @0()

pubsub.psubscribe(**{'__keyevent@0__:expired': event_handler})

如果有数据,get_message()将读取并返回它。如果没有数据,则返回None。
从pubsub实例读取的每条消息都是一个包含以下键的字典:

键入下列之一:subscribe,unsubscribe,psubscribe,punsubscribe,message,pmessage

  • channel:订阅的频道或发布消息的频道
  • pattern:匹配已发布消息的通道的模式(除类型外在所有情况下均为Nonepmessage)
  • data:消息数据

参考:https://cloud.tencent.com/developer/article/1347437

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值