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

sql1:查询商品库存

1
2
3
4
5
if(库存数量 > 0)
{
  //生成订单...
  sql2:库存-1
}

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

解决这个问题比较流行的思路:

1.用额外的单进程处理一个队列,下单请求放到队列里,一个个处理,就不会有并发的问题了,但是要额外的后台进程以及延迟问题,不予考虑。

2.数据库乐观锁,大致的意思是先查询库存,然后立马将库存+1,然后订单生成后,在更新库存前再查询一次库存,看看跟预期的库存数量是否保持一致,不一致就回滚,提示用户库存不足。

3.根据update结果来判断,我们可以在sql2的时候加一个判断条件update ... where 库存>0,如果返回false,则说明库存不足,并回滚事务。

4.借助文件排他锁,在处理下单请求的时候,用flock锁定一个文件,如果锁定失败说明有其他订单正在处理,此时要么等待要么直接提示用户"服务器繁忙"

本文要说的是第4种方案,大致代码如下:

阻塞(等待)模式

1
2
3
4
5
6
7
8
9
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX))
{
  //..处理订单
  flock($fp,LOCK_UN);
}
fclose($fp);
?>

非阻塞模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX | LOCK_NB))
{
  //..处理订单
  flock($fp,LOCK_UN);
}
else
{
  echo "系统繁忙,请稍后再试";
}
 
fclose($fp);
?>

php秒杀的更多相关文章

  1. Web系统大规模并发——电商秒杀与抢购

    电商的秒杀和抢购,对我们来说,都不是一个陌生的东西.然而,从技术的角度来说,这对于Web系统是一个巨大的考验.当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要.这次我们 ...

  2. ecshop 秒杀并发时库存会被减到小于0的解决办法

    ecshop 秒杀并发时库存会被减到小于0更新库存后,再进行库存检查,如果库存为负数,则执行事务的回滚. begin();//开始一个事物处理开始 $sql = "UPDATE " ...

  3. php结合redis实现高并发下的抢购、秒杀功能

    抢购.秒杀是如今很常见的一个应用场景,主要需要解决的问题有两个:1 高并发对数据库产生的压力2 竞争状态下如何解决库存的正确减少("超卖"问题)对于第一个问题,已经很容易想到用缓存 ...

  4. PHP解决抢购、秒杀、抢楼、抽奖等阻塞式高并发库存防控超量的思路方法

    如今在电商行业里,秒杀抢购活动已经是商家常用促销手段.但是库存数量有限,而同时下单人数超过了库存量,就会导致商品超卖甚至库存变负数的问题. 又比如:抢购火车票.论坛抢楼.抽奖乃至爆红微博评论等也会引发 ...

  5. redis使用watch完成秒杀抢购功能

    Redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...

  6. SSM框架学习之高并发秒杀业务--笔记5-- 并发优化

    前几节终于实现了这个高并发秒杀业务,现在问题是如何优化这个业务使其能扛住一定程度的并发量. 一. 优化分析 对于整个业务来说,首先是分析哪些地方会出现高并发,以及哪些地方会影响到了业务的性能.可能会出 ...

  7. 基于redis分布式锁实现“秒杀”

    转载:http://blog.5ibc.net/p/28883.html 最近在项目中遇到了类似“秒杀”的业务场景,在本篇博客中,我将用一个非常简单的demo,阐述实现所谓“秒杀”的基本思路. 业务场 ...

  8. Web系统大规模并发——电商秒杀与抢购 【转】

    电商的秒杀和抢购,对我们来说,都不是一个陌生的东西.然而,从技术的角度来说,这对于Web系统是一个巨大的考验.当一个Web系统,在一秒钟内收到数以万计甚至更多请求时,系统的优化和稳定至关重要.这次我们 ...

  9. 徐汉彬:Web系统大规模并发——电商秒杀与抢购(转)

    [导读]徐汉彬曾在阿里巴巴和腾讯从事4年多的技术研发工作,负责过日请求量过亿的Web系统升级与重构,目前在小满科技创业,从事SaaS服务技术建设. 电商的秒杀和抢购,对我们来说,都不是一个陌生的东西. ...

  10. redis使用watch完成秒杀抢购功能(转)

    redis使用watch完成秒杀抢购功能: 使用redis中两个key完成秒杀抢购功能,mywatchkey用于存储抢购数量和mywatchlist用户存储抢购列表. 它的优点如下: 1. 首先选用内 ...

随机推荐

  1. Class.forName()

    主要功能 Class.forName(xxx.xx.xx)返回的是一个类 Class.forName(xxx.xx.xx)的作用是要求JVM查找并加载指定的类, 也就是说JVM会执行该类的静态代码段 ...

  2. 1、JavaScript基础

    1.思维导图 2.创建html页面 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...

  3. 从零开始学Axure原型设计(高级篇)

    如果你熟悉了Axure的部件库,那么你可以得心应手地画出心目中产品的线框图:如果你会用Axure的母版.动态面板功能,那么你应该能够画出一些简单网站的原型图:但只有你精通了Axure的条件逻辑.变量. ...

  4. centos 6 安装docker

    安装 Fedora EPEL 1.yum -y install http://dl.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarc ...

  5. LeetCode OJ 152. Maximum Product Subarray

    Find the contiguous subarray within an array (containing at least one number) which has the largest ...

  6. CodeForces 605A Sorting Railway Cars 思维

    早起一水…… 题意看着和蓝桥杯B组的大题第二道貌似一个意思…… 不过还是有亮瞎双眼的超短代码…… 总的意思呢…… 就是最长增长子序列且增长差距为1的的…… 然后n-最大长度…… 这都怎么想的…… 希望 ...

  7. jQuery版本冲突解决办法

    <!-- 引入1.6.4版的jq --> <script src="<a href="http://ajax.googleapis.com/ajax/lib ...

  8. WTL版本ACEdit控件,改写自MFC版,附带源码

    自动完成是个很酷也很实用的功能,比如在浏览器地址栏输入几个字母,相关的记录就会在下拉框中陈列出来. 最近在做公司产品UI部分的改善,原版本是MFC做的,我决定用WTL,于是就遇到自动完成控件的问题.遍 ...

  9. 关于maven相互依赖的工程部署问题

    环境:win7 64位,myeclipse10.6,eclipse4.5,都配置了svn插件 问题描述:1.工程模块化之后都是通过pom配置model来关联的,svn提交之后,通过myeclipse的 ...

  10. CSS的标签类型

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...