我们知道数据库处理sql是一条条处理的,假设购买商品的流程是这样的:

sql1:查询商品库存

if(库存数量 > 0)

{

//生成订单...

sql2:库存-1

}

当没有并发时,上面的流程看起来是如此完美,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,要么补库存,要么等用户投诉吧。

解决这个问题比较好的方法是什么呢?

回复内容:

我们知道数据库处理sql是一条条处理的,假设购买商品的流程是这样的:

sql1:查询商品库存

if(库存数量 > 0)

{

//生成订单...

sql2:库存-1

}

当没有并发时,上面的流程看起来是如此完美,假设同时两个人下单,而库存只有1个了,在sql1阶段两个人查询到的库存都是>0的,于是最终都执行了sql2,库存最后变为-1,超售了,要么补库存,要么等用户投诉吧。

解决这个问题比较好的方法是什么呢?

用事务处理机制

数据表加锁也行(如果你用InnoDB引擎就用行锁;如果你用MyISAM引擎就用表锁)

库存字段改成unsigned int。

这样的话不会<0,顶多就SQL执行出错。

也可以用memcached/redis来缓存结果,从缓存中查询。

1.MySQL数据库加锁,乐观锁 和 悲观锁

2.用队列,排队逐一去生成订单

库存缓存一般都是 有的吧,如果有并发需求。 还有就是加锁,或者放到队列执行sql。

有种很笨的方法,已楼主的假设为例:

sql1:查询商品库存 (假设查出的库存为10)

if(10 > 0)

{

//生成订单...

sql2: 10 - 1 (此时库存为9了)

//再校验库存

sql3: 查询商品库存 == 9 (如果此时有并发情况,那查出来的库存可能为8、7等,这时抛出异常,事务回滚,该笔订单无效。)

}

处理高并发一般来说都会用到Redis,使用Redis的list数据结构(高并发当然要异步队列咯)来存储请求过来的订单信息,然后启用redis的事务机制(见:http://redis.io/topics/transactions),加入指定key的list前,判断该list等长度是否超过redis中保存的指定商品库存值,如果超过则不操作,如果不超过,则进行插入,插入之后,再次判断该list的长度是否超过redis中保存的指定商品的库存值,如果超过则回滚,否则提交。

想问一下,并发量大的情况下,是怎么做的呢?

1.用事务保持操作原子性,

2.在修改库存的时候先用select...for update把数据锁好

update table set n = n-x where n >= x

不需要事务,直接获取affected row count来判断是否扣成功,后到的那一条因为n=0,affected row肯定为0

相关标签:php 并发

本文原创发布php中文网,转载请注明出处,感谢您的尊重!

php无法下单功能,PHP如何解决并发下单问题?(不一定是下单,举个例)相关推荐

  1. Redis实现全局唯一id,实现优惠卷秒杀的下单功能

    Redis实现全局唯一id public class RedisIdWorker {private StringRedisTemplate stringRedisTemplate;public Red ...

  2. mysql 乐观锁_使用Mysql乐观锁解决并发问题

    使用mysql乐观锁解决并发问题 案例说明 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...

  3. 关于解决并发问题,99%的程序员都会忽略的一个重要方案!

    △Hollis, 一个对Coding有着独特追求的人△ 这是Hollis的第 370 篇原创分享 作者 l zyz1992 来源 l Hollis(ID:hollischuang) 在并发编程的世界里 ...

  4. mysql使用条件限制乐观锁_使用Mysql乐观锁解决并发问题

    使用mysql乐观锁解决并发问题 案例说明 银行两操作员同时操作同一账户.比如A.B操作员同时读取一余额为1000元的账户,A操作员为该账户增加100元,B操作员同时为该账户扣除50元,A先提交,B后 ...

  5. cas无法使用_【漫画】CAS原理分析!无锁原子类也能解决并发问题!

    本文来源于微信公众号[胖滚猪学编程].转载请注明出处 在漫画并发编程系统博文中,我们讲了N篇关于锁的知识,确实,锁是解决并发问题的万能钥匙,可是并发问题只有锁能解决吗?今天要出场一个大BOSS:CAS ...

  6. 访问数据库时如何解决并发问题

    解决并发主要是用到了锁和事务. 锁  :给记录或表加上锁是为了对当前操作对象加上一个状态表示位,          让其他用户在获取编辑权限时有了判断. 事务:是为了确保一组操作的完整性.(要么就全部 ...

  7. 打车网约车代驾APP软件主要功能及要解决的痛点

    一.打车软件主要功能及要解决的痛点: 1.多种打车模式:快车.专车.顺风车.城际城乡车.分流车.拼车.代驾.出租车.货运.城际巴士等多种业务模式 2.多终端:微信公众号.微信小程序.Android软件 ...

  8. vue2 + vuex 高度还原 饿了么 App,用真实数据登陆官网,并实现购物车、下单功能

    前言 vue2的发布后自己也研究了一段时间,奈何公司的技术栈是以react为主,没有机会好好利用vue2去做一个完整的项目.虽然写了几个demo,但和写一个完整的项目还是有很大差别的.于是自己想着用空 ...

  9. mysql myisam 并发_MySQL的myisam解决并发读写解决方法

    MySQL的myisam解决并发读写解决方法MyISAM在读操作占主导的情况下是很高效的.可一旦出现大量的读写并发,同InnoDB相比,MyISAM的效率就会直线下降,而且,MyISAM和InnoDB ...

最新文章

  1. 在SpringBoot的Web项目中使用于Thymeleaf(二)
  2. ubuntu 用命令行设置chrome的proxy
  3. 从落后的传统WAN转向SD-WAN—Vecloud
  4. process 类 java_编写可执行jar——java的Process类的使用(二)
  5. C语言 · 数的读法
  6. python thread 共享数据
  7. Linux 内核全系更新 3.6.2、3.5.7 等
  8. 【技术美术图形部分】纹理基础2.0-凹凸映射
  9. Requests爬取chinadaily海量新闻数据
  10. Adobe Photoshop Lightroom 5.7.1
  11. 隆重推荐:吴闲云 - 三国中的博弈
  12. 去中心化身份 DID( Decentralized Identifiers)
  13. 家用计算机中PCB板材质,主流的PCB板材料有哪些分类?
  14. 天河二号上运行ZHT(a zero-hop distributed table)
  15. ProxySQL+MGR实现读写分离和主节点故障无感知切换
  16. 脱离低级趣味- Python ‘\r‘, ‘\n‘, ‘\r\n‘ 的彻底理解
  17. 《掌舵》-还原一个真实的政商圈
  18. Linux 实用指令 -- 网络配置(查看网络IP和网关、 ping 测试主机之间网络连通、Linux网络环境配置(指定固定ip))
  19. [Err] 1813 - Tablespace ‘`XX`.`XX`‘ exists.
  20. linux压缩分区大小,linux如何无损调整分区大小的详细介绍

热门文章

  1. 皇nity webgl与html交互文件,Vue与UnityWebGl交互通信
  2. CodeDay 北京站报名倒计时
  3. 「技术人生」:什么是技术一号位?
  4. 在unity2d同屏显示9千人
  5. 依赖注入 这样的坑游戏编程要谨慎
  6. 经验分享:聊聊多人游戏同步那点事
  7. 《球球大作战》游戏优化之路(下)
  8. 从应用到底层 36张图带你进入Redis世界
  9. 使用NOSQL的MongoDB时建立索引需要注意的几点建议和Explain优化分析
  10. 用mysqlbinlog查看row格式的事件