避免电子商务场景中的竞争条件

时间:2010-08-02 15:03:09

标签: php database e-commerce race-condition payment-processing

我的客户有一个销售电子产品的电子商务网站,并且有些情况下产品的销售次数超过库存次数。这是因为如果两个用户在库存中只剩下一个产品的同时购买产品,则一个会话在另一个会话开始之前没有完成将产品注销为售完(所以它继续正常,认为有一个左)即使在过程开始时有一个检查。这显然会花钱(退款费,退款等)和消费者的不便。

所以我想知道是否还有解决这个问题?我想在流程开始时创建一个“标记”,即它会检查库存,如果售罄,它会标记产品,从而阻止其他会话购买。但这也会产生更多问题:如果客户端发生某些事情会导致他们取消中间过程(断电等),那么即使产品被标记为已售出,但自结账以来它实际上并未售出过程没有完成。如果这种情况持续发生,那么产品就会积压。其次,会话还可以检查库存,而另一个会话将其标记为已售出,因此即使第二个会话已经购买,第一个会话也将继续。这导致我们回到最初的问题。

我正在查看数据库端的表锁定,但我不确定这是不是最好的主意。任何建议都将受到高度赞赏!

谢谢, dyip

2 个答案:

答案 0 :(得分:1)

您可以设置故障保险,以便在用户结账时下订单,但在订单发货之前,用户的信用卡实际上并未收费。然后,对于库存已用完的情况,您可以通过电子邮件向这些客户发送电子邮件并告诉他们“抱歉,我们已售罄X,您不会被收费等”。

您可以在下一个订单上给予他们某种折扣作为补偿,但这个过程可以避免任何退款费用,退款等,因为他们从未实际收取没有库存的订单。

当然,听起来这会改变网站处理订单的方式,并且必须让每个订单准备好后让某人将信息输入系统。此外,在下订单之前,您需要对卡进行一些验证才能知道它是有效的,以防止欺诈 - 尽管可能是网站已经这样做了吗?

答案 1 :(得分:0)

我建议你做以下事情:

  1. 当产品添加到购物车时,不要减少产品的库存可用性;你不想错过任何可能的未来出售;
  2. 当用户决定开始结帐流程,然后在后端,您可以将购物车中的所有商品标记为保留,方法是将它们添加到单独的数据库表中。
  3. 如果用户B稍后启动结帐流程,那么您可以再次检查购物车中每种产品的可用性,如下所示:

    productAvailability - quantityReservedForThisProduct >= quantityRequested
    

    如果上述条件为假,则表示其他人已表示愿意购买。因此,您可以让您的用户了解当前情况。

    简而言之,如果其他人已经开始结账过程,他会自动保留这些产品。

  4. 然后,当第一个用户的付款成功时,我们更新包含保留产品的表格和存储实际产品的表格,即减少库存可用性。

  5. 此外,我们不希望处于用户保留产品(即启动结账流程)但从未购买产品的情况。因此,您可以引入 TTL 机制。因此,在固定的时间间隔内,您可以删除超过固定时间的结帐流程。

    例如,如果用户启动了结帐流程,但在10分钟之后尚未完成,则将其从数据库中删除并释放保留的产品。

  6. 在我的脑海里,我还没有测试过这种方法;