关于redis开启事务机制的问题

关于redis开启事务机制的问题

老师在这个课堂内容中,关于撰写redis事务机制模拟秒杀活动我有问题:

代码块1:

try:
    if connection.exists('kill_flag') == 1:
        pipline.watch('kill_num','kill_user')
        total = int(pipline.get('kill_total').decode('utf-8'))
        num = int(pipline.get('kill_num').decode('utf-8'))
        if num < total:
            pipline.multi()
            pipline.incr('kill_num')
            user_id = s.pop()
            pipline.rpush('kill_user', user_id)
            pipline.execute()

代码块2:

for i in range(0, 1000):
    executor.submit(buy)

1)按照之前课程所描述的,当redis开启pipline.watch('kill_num', 'kill_user')时开启事务pipline.multi()后,当线程池异步执行buy任务的时候相当于有多个redis客户端同时修改pipline.watch()中的参数kill_num的数值,依照redis的事务机制当被检测的数据记录发生变化的时候,处在运行阶段的事务会被中断,那么在kill_num不断变化的阶段(kill_num<50的情况下)随着线程不断执行,redis中关于if num < total:以下的业务都会随着kill_num的数量不断加1而反复的终止业务

2)在这种情况下,redis在事务在由于kill_num不断变化的情况下不断被打断,这种情况下是如何能将pipline.rpsh('kill_user', user_id)以及kill_num等数据写入到redis中的?

这个逻辑我有些发蒙,绕不出来了,谢谢老师解答。

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学,你好!redis 是事务相当于批处理,先将multi()到execute()之间的代码指令保存下来,当执行到execute()时,才会将保存的指令发送到redis去执行。假设客户端A(A用户)在修改kill_num,B客户端也要执行事务,当B客户端发现客户端A 在修改kill_num,那么B客户端的事务就关闭取消了,本次秒杀失败了。只能再次重新秒杀,重新开始事务并提交。不是提交就能成功的,什么时候提交的事务发现没有客户端在改数据,才会执行事务,所以才称为秒杀。同学可以看下视频:https://class.imooc.com/lesson/2182#mid=51488的8:20秒处---9:30秒和11:00--12:30秒处的内容


祝学习愉快~

  • 懒惰的围脖 提问者 #1

    可以理解为在某一瞬间时间之内(很快啊),线程池内执行抢购的某一线程在执行buy任务不受到其他客户端秒杀的影响
    例如在0.1s中这个时刻其他用户都没有执行操作,但这个时间之内仅有我执行了并且在这一时刻之中完成了pipline.multi()到pipline.excute()的全部内容,因此秒杀成功数据成功缓存在了redis中。

    2023-10-16 15:51:54
  • 好帮手慕小猿 回复 提问者 懒惰的围脖 #2

    同学,你好!理解的正确

    祝学习愉快~

    2023-10-16 17:06:17
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星

相似问题

登录后可查看更多问答,登录/注册

请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师