先来就库存超卖的问题作描述:一般电子商务网站都会遇到如团购、秒杀、特价之类的活动,而这样的活动有一个共同的特点就是访问量激增、上千甚至上万人抢购 一个商品。然而,作为活动商品,库存肯定是很有限的,如何控制库存不让出现超买,以防止造成不必要的损失是众多电子商务网站程序员头疼的问题,这同时也是 最基本的问题。

从技术方面剖析,很多人肯定会想到事务,但是事务是控制库存超卖的必要条件,但不是充分必要条件。

举例:

总库存:4个商品

请求人:a、1个商品 b、2个商品 c、3个商品

程序如下:

beginTranse(开启事务)

try{

$result = $dbca->query('select amount from s_store where postID = 12345');

if(result->amount > 0){

//quantity为请求减掉的库存数量

$dbca->query('update s_store set amount = amount - quantity where postID = 12345');

}

}catch($e Exception){

rollBack(回滚)

}

commit(提交事务)

以上代码就是我们平时控制库存写的代码了,大多数人都会这么写,看似问题不大,其实隐藏着巨大的漏洞。数据库的访问其实就是对磁盘文件的访问,数据库中的

表其实就是保存在磁盘上的一个个文件,甚至一个文件包含了多张表。例如由于高并发,当前有三个用户a、b、c三个用户进入到了这个事务中,这个时候会产生

一个共享锁,所以在select的时候,这三个用户查到的库存数量都是4个,同时还要注意,mysql

innodb查到的结果是有版本控制的,再其他用户更新没有commit之前(也就是没有产生新版本之前),当前用户查到的结果依然是就版本;

然后是update,假如这三个用户同时到达update这里,这个时候update更新语句会把并发串行化,也就是给同时到达这里的是三个用户排个序,

一个一个执行,并生成排他锁,在当前这个update语句commit之前,其他用户等待执行,commit后,生成新的版本;这样执行完后,库存肯定为

负数了。但是根据以上描述,我们修改一下代码就不会出现超买现象了,代码如下:

beginTranse(开启事务)

try{

//quantity为请求减掉的库存数量

$dbca->query('update s_store set amount = amount - quantity where postID = 12345');

$result = $dbca->query('select amount from s_store where postID = 12345');

if(result->amount < 0){

throw new Exception('库存不足');

}

}catch($e Exception){

rollBack(回滚)

}

commit(提交事务)

另外,更简洁的方法:

beginTranse(开启事务)

try{

//quantity为请求减掉的库存数量

$dbca->query('update s_store set amount = amount - quantity where

amount>=quantity andpostID = 12345');

}catch($e Exception){

rollBack(回滚)

}

commit(提交事务)

=====================================================================================

1、在秒杀的情况下,肯定不能如此高频率的去读写数据库,会严重造成性能问题的

必须使用缓存,将需要秒杀的商品放入缓存中,并使用锁来处理其并发情况。当接到用户秒杀提交订单的情况下,先将商品数量递减(加锁/解锁)后再进行其他方面的处理,处理失败在将数据递增1(加锁/解锁),否则表示交易成功。

当商品数量递减到0时,表示商品秒杀完毕,拒绝其他用户的请求。

2、这个肯定不能直接操作数据库的,会挂的。直接读库写库对数据库压力太大,要用缓存。

你要卖出的商品比如10个商品放到缓存中;然后在memcache里设置一个计数器来记录请求数,这个请求书你可以以你要秒杀卖出的商品数为基数,比如你

想卖出10个商品,只允许100个请求进来。那当计数器达到100的时候,后面进来的就显示秒杀结束,这样可以减轻你的服务器的压力。然后根据这100个

请求,先付款的先得后付款的提示商品以秒杀完。

3、首先,多用户并发修改同一条记录时,肯定是后提交的用户将覆盖掉前者提交的结果了。

这个直接可以使用加锁机制去解决,乐观锁或者悲观锁。

乐观锁,就是在数据库设计一个版本号的字段,每次修改都使其+1,这样在提交时比对提交前的版本号就知道是不是并发提交了,但是有个缺点就是只能是应用中控制,如果有跨应用修改同一条数据乐观锁就没办法了,这个时候可以考虑悲观锁。

悲观锁,就是直接在数据库层面将数据锁死,类似于oralce中使用select xxxxx from xxxx where xx=xx for update,这样其他线程将无法提交数据。

除了加锁的方式也可以使用接收锁定的方式,思路是在数据库中设计一个状态标识位,用户在对数据进行修改前,将状态标识位标识为正在编辑的状态,这样其他用

户要编辑此条记录时系统将发现有其他用户正在编辑,则拒绝其编辑的请求,类似于你在操作系统中某文件正在执行,然后你要修改该文件时,系统会提醒你该文件

不可编辑或删除。

4、不建议在数据库层面加锁,建议通过服务端的内存锁(锁主键)。当某个用户要修改某个id的数据时,把要修改的id存入memcache,若其他用户触发修改此id的数据时,读到memcache有这个id的值时,就阻止那个用户修改。

5、实际应用中,并不是让mysql去直面大并发读写,会借助“外力”,比如缓存、利用主从库实现读写分离、分表、使用队列写入等方法来降低并发读写。

mysql 高并发扣除库存_【并发】mysql处理高并发,防止库存超卖相关推荐

  1. keepalived mysql双主架构图_基于MySQL双主的高可用解决方案理论及实践

    MySQL在互联网应用中已经遍地开花,但是在银行系统中,还在生根发芽的阶段.本文记录的是根据某生产系统实际需求,对数据库高可用方案从需求.各高可用技术特点对比.实施.测试等过程进行整理,完善Mysql ...

  2. 抢购 mysql 优化_处理抢购、秒杀应用场景降低“超卖”发生几个优化方案(php)...

    加深下文件锁理论 flock-轻便的咨询文件锁定 说明 参数 handle 文件系统指针,是典型地由fopen()创建的resource(资源). operation operation可以是以下值之 ...

  3. mysql如何加悲观锁_【mysql】关于悲观锁

    关于mysql中的锁 在并发环境下,有可能会出现脏读(Dirty Read).不可重复读(Unrepeatable Read). 幻读(Phantom Read).更新丢失(Lost update)等 ...

  4. 收集关于MySQL数据库的相关知识_关于Mysql数据库的知识总结

    2017年6月8日,天气阴.心情晴. 连续做梦两个晚上了,昨晚竟然梦见一个很长时间不联系的初中同学了,早上上班的路上聊了聊.女孩现在出差在贵州,风景秀美的地方.我说"你现在生活很滋润&quo ...

  5. mysql MDL锁如何解决_理解MySQL的MDL元数据锁

    一.MDL锁的作用 MySQL DBA 对于 Waiting for table metadata lock 肯定不会陌生,一般都是进行 alter 操作时被堵住了,导致了我们在 show proce ...

  6. mysql和python的关系_八MySQL与Python

    <1>数据库介绍 什么是数据库? 数据库(Database)是按照数据结构来组织.存储和管理数据的仓库, 每个数据库都有一个或多个不同的API用于创建,访问,管理,搜索和复制所保存的数据. ...

  7. mysql 自动化运维工具_部署MySQL自动化运维工具inception+archer

    *************************************************************************** 部署MySQL自动化运维工具inception+ ...

  8. mysql 按时间累计计算_精通MySQL索引背后的数据结构及算法原理

    本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,mysql支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BTree ...

  9. mac下安装mysql 5.7.11卡住_【mysql】Mac下安装mysql5.7 完整步骤,大坑已解决

    最近使用Mac系统,准备搭建一套本地web服务器环境.因为Mac系统自带PHP和apach,但是没有自带mysql,所以要手动去安装mysql,本次安装mysql最新版5.7.17. 1.官网下载 点 ...

  10. MySQL数据库实用教程考核_《MySQL数据库实用教程》郑明秋,蒙连超,赵海侠【pdf】...

    内容简介 郑明秋.蒙连超.赵海侠主编的<MySQL数据库实用教程>是作者在多年的数据库开发实践与教学经验的基础上,根据计算机相关专业的职业岗位能力需求及学生的认知规律倾心组织编写的.本教材 ...

最新文章

  1. 美团确定进军自动驾驶,滴滴如何应对?
  2. linux iscsi 服务端,Linux的iscsi磁盘服务
  3. sap Bydesign 中解决添加元素或者字段时,多语言翻译的问题
  4. android 解决getNetworkInfo过时
  5. 前端学习(2462):打包优化
  6. C/C++如何连接MySQL服务器以及简单加密
  7. linux命令备记(一)
  8. 面试题解析:1 Java中switch语句可以作用在enum上的测试
  9. 六级词汇打卡第天四天(四)
  10. python的常量变量_Python基础语法-常量与变量
  11. php微博api发布微博代码,使用新浪微博API的OAuth认证发布微博实例
  12. 黑苹果 dmg,cdr和iso的区别
  13. 计算机公式求时间差公式,日期差计算(Excel表格中如何计算日期、时间差)
  14. git中fatal: Authentication failed for 的问题
  15. 宇宙也能测量,破解未解之谜的三维地图出炉
  16. oa系统需要的服务器配置,oa办公系统需要服务器配置
  17. STM32定时器输入捕获,脉宽测量知识点
  18. AWS两个VPC网络互通
  19. FileSaver.js下载图片
  20. java 编写线程公共类_Java实现线程间通信方式

热门文章

  1. LeetCode 12 数字转化为罗马符号(难度: Medium)
  2. ios中嵌套h5做的app,长按图片默认会有放大效果;如何禁止
  3. android计算器开源小项目代码(附安装包.apk)
  4. codeforces1395D 贪心
  5. 50G-PON,继10G PON之后的新一代PON技术
  6. echart 三维可视化地图_可视化地图是什么?推荐3个工具!
  7. Pytorch系列笔记(二)
  8. HTML边框圆角椭圆原理,CSS3教程:border-radius你以为就是个圆角边框吗?
  9. 微信安卓协议分析笔记
  10. 前辈们整理的SAP的相关链接