我们知道数据库处理sql是一条条处理的,假设购买商品的流程是这样的:
<code>sql1:查询商品库存
if(库存数量 > 0)
{
//生成订单...
sql2:库存-1
}
</code>当没有并发时,上面的流程看起来是如此完美,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,要么补库存,要么等用户投诉吧。
解决这个问题比较好的方法是什么呢?
我们知道数据库处理sql是一条条处理的,假设购买商品的流程是这样的:
<code>sql1:查询商品库存
if(库存数量 > 0)
{
//生成订单...
sql2:库存-1
}
</code>当没有并发时,上面的流程看起来是如此完美,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,要么补库存,要么等用户投诉吧。
解决这个问题比较好的方法是什么呢?
用事务处理机制
立即学习“PHP免费学习笔记(深入)”;
数据表加锁也行(如果你用InnoDB引擎就用行锁;如果你用MyISAM引擎就用表锁)
库存字段改成unsigned int。
这样的话不会也可以用memcached/redis来缓存结果,从缓存中查询。
1.MySQL数据库加锁,乐观锁 和 悲观锁
2.用队列,排队逐一去生成订单
如今有越来越多的人在网上做代驾,打造一个代驾平台,既可以让司机增加一笔额外的收入,也解决了车主酒后不能开发的问题,汉潮代驾系统基于微信小程序开发的代驾系统支持一键下单叫代驾,支持代驾人员保证金功能,支持代客下单,支持代驾人员订单调度及代驾人员位置查看,欢迎大家关注我们。 汉潮代驾系统是汉潮唐越科技有限公司研发团队自主开发的代驾系统,包含后台系统和微信小程序,主要功能模块商家设置,会员管理,营销管理
0
库存缓存一般都是 有的吧,如果有并发需求。 还有就是加锁,或者放到队列执行sql。
有种很笨的方法,已楼主的假设为例:
<code>sql1:查询商品库存 (假设查出的库存为10)
if(10 > 0)
{
//生成订单...
sql2: 10 - 1 (此时库存为9了)
//再校验库存
sql3: 查询商品库存 == 9 (如果此时有并发情况,那查出来的库存可能为8、7等,这时抛出异常,事务回滚,该笔订单无效。)
}</code>
处理高并发一般来说都会用到Redis,使用Redis的list数据结构(高并发当然要异步队列咯)来存储请求过来的订单信息,然后启用redis的事务机制(见:http://redis.io/topics/transactions),加入指定key的list前,判断该list等长度是否超过redis中保存的指定商品库存值,如果超过则不操作,如果不超过,则进行插入,插入之后,再次判断该list的长度是否超过redis中保存的指定商品的库存值,如果超过则回滚,否则提交。
想问一下,并发量大的情况下,是怎么做的呢?
1.用事务保持操作原子性,
2.在修改库存的时候先用select...for update把数据锁好
<code class="sql">update table set n = n-x where n >= x</code>
不需要事务,直接获取affected row count来判断是否扣成功,后到的那一条因为n=0,affected row肯定为0
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号