抢购

作者: 机智的老刘明同志 | 来源:发表于2018-10-19 08:01 被阅读21次

方案一:

        收到抢购请求后,对商品执行库存 -1 操作。然后给用户生成一个订单。

        这系列操作中,并发问题在于:如果库存为1,这时候有两个用户同一时间请求,那么两个进程同时select 到库存数为1,并同时进行update -1操作,那么相当于1件商品就卖出去了两次。

        那么如何解决这个问题呢?很简单。我们只需要把select库存和update库存-1这两个操作放在1个事务里,并且在select商品库存的时候for update一下加上排他锁。那么就不存在两人同时读取到库存1的可能了。第一个人-1库存,+1订单,提交事务。第二人才能select到库存。这时候库存就是0了。自然而然就是抢购失败。

        上面是理论。实际操作中,有更简单的办法。那就是直接update 商品表 库存-1 where id=商品id AND 库存!=0;然后获取更新数量,如果不为1,就是抢购失败。为1,就是抢购成功。这里面保证并发安全的是数据库的单条sql就是一个事务的特性保证的。

        优化方案1:将 库存 字段 设为unsigned,当库存为0时,因为字段不能为负数,将会返回false

        优化方案2:使用mysql的事务,锁住操作的行

        https://blog.csdn.net/canot/article/details/53815294 (未完)

方案二:文件锁

方案三:Memcache锁

        使用product_lock_key 为票锁key

        当product_key存在于memcached中时,所有用户都可以进入下单流程。

        当进入支付流程时,首先往memcached存放add(product_lock_key, “1″),如果返回成功,进入支付流程。如果不成,则说明已经有人进入支付流程,则线程等待N秒,递归执行add操作。

方案四:redis队列(rpoplpush的安全队列)

将商品加入redis队列中

        一般情况下,我们可以借助List来实现消息队列,比如一个客户端通过命令LPUSH(BLPUSH)把消息入队,另一个客户端通过命令RPOP(BRPOP)获取消息。这种方式实现的队列是不安全的。

        为什么是不安全的呢?因为RPOP命令的特性:会移除list的队尾元素(消息),并将这个元素(消息)返回给客户端。这意味着该元素就只存在于客户端的上下文中,redis服务器中没有这个元素了,如果客户端在处理这个返回元素的过程崩溃了,那么这个元素就永远丢失了。这种情况导致:客户端虽然成功收到了消息,但是却没有处理它。

        那怎么来实现一个安全的队列呢?可以使用redis的 RPOPLPUSH (或者其阻塞版本的 BRPOPLPUSH)命令。

        RPOPLPUSH命令格式:RPOPLPUSH  source  destination 。RPOPLPUSH命令原子性地返回并移除 source 列表的最后一个元素, 并把该元素放入 destination 列表的头部。使用这个命令就可以实现安全队列。

        因为使用 RPOPLPUSH 获取消息时,RPOPLPUSH 会把消息返给客户端,同时把该消息放入一个备份消息列表,并且这个过程是原子的,可以保证消息的安全。当客户端成功的处理了消息后,就可以把此消息从备份列表中移除了。如果客户端因为崩溃的原因没有处理某个消息,那么就可以从备份列表destination中重新获取并处理这个消息。

相关文章

  • 只用数据库设计高效抢购业务

    不使用缓存(redis、memcache),如何设计高效抢购业务呢?常见的抢购业务主要有:商品抢购券抢购红包抢购今...

  • 抢购

    方案一: 收到抢购请求后,对商品执行库存 -1 操作。然后给用户生成一个订单。 这系列操作中,并发问题在于:如果库...

  • 抢购

    今天,不,准确的说是昨晚,一直很期盼多宝出牙,可是总也看不见小牙的影子,昨晚睡前玩耍的时候,试着摸了一下他...

  • 抢购

    有些东西一打折就会有很多人购买,可能买回来也不用,也不是自己需要的东西,但就是想买,人如果自己的时候比较理智,让在...

  • 抢购

    元旦之前的一个周末,去*润*果超市买一种煲汤小锅,我准备提货付款时导购员竟小声地对我说:“你干嘛非要今天买呢?元旦...

  • 抢购

    家里一棵青菜也没有了,今天我们开车去买菜。 我观察着路上的行人,十个有7个戴口罩的,还有3个不戴的,不戴口罩的多数...

  • 抢购

    又新一波疫情的影响,再加之进入腊月了,物价现在又有所上涨。 上午的时候和包子他奶奶推着包子出去溜溜顺便去买点鸡蛋。...

  • 抢购

    昨天去超市买酸奶,赶上周年庆的最后一天促销,本想买了酸奶就走,可还是想看看都有什么优惠的商品。 一楼去看肉,猪肉8...

  • 抢购

    附近新超市开张,婆婆去抢了一堆东西回来,说好便宜,还让我去买,我才不去,买那么多放着都不新鲜了!和一群婆婆们抢,我...

  • 抢购

    时间过得很快,眨眼又到双11啦。记忆中以往的今天都在忙着上班,想购物却没时间抢购。今天虽然略显空闲,但也只...

网友评论

      本文标题:抢购

      本文链接:https://www.haomeiwen.com/subject/fiwezftx.html