商城并发抢购库存减至负数问题


现在公司的购物商城限时抢够出现了这如下问题
当某商品库存只有1的时候,并发进入多个用户点击购买此商品,所有用户读取到的库存都为1.
然后下单,对库存--,此时问题就出现了这么多用户进行--库存就变为了负数。
这样就出现了超售的问题。

我想过几种方法来解决这个问题

1.增加一条队列,对并发下单的用户进行排队的操作处理。(这样的话,如果并发数量很大,某些用户等待的时候就会很长)

2.利用mysql的事务处理,其实原理等同于排队。当A,B同时并发进来,开启事务。A执行update操作,B执行update操作,在A没有commit之前B是update是一直处于等待状态的。
那么A执行update之后select出update的那个字段看库存是否为0为0 commit,不为0 rollback。

3.同样为mysql处理,这次是写一条check限制库存数量。就是当update库存出现小于0的时候check会报错,catch到异常之后处理。

以上就是我想的方法,感觉都不太好用,望各位指点迷津。。。

@山水 的那個解決方法的確是解決了-為負的問題。但是如果庫存還有很多,但併發很高的時候,就會發生只有一人能下單成功的情況(極端情況)。
現在考慮將sql改為 where stock > 0 或 where stock = {$curr_stock} or stock > 0
同樣不會減至負數。

@victorzuo 的辦法應該也是可行,但由於項目我不是所有代碼能改所以沒去測試。

架构设计 php

出家人的愤怒 11 years, 2 months ago

有个简单的解决方案。

就是在update时,代入之前的库存作为条件,如:
update stocks set count=count-1 where count=20 and productid=xxxx

这样,在并发时,如果存在多条同时update,那么只有一条是成功的,其他的不会写入数据,也不需要回滚,只需要获得是否update成功的信息,就转去相应的处理界面就可以了。

Yoniya answered 11 years, 2 months ago

Your Answer