zoukankan      html  css  js  c++  java
  • MYSQL处理高并发,防止库存超卖(图解)

     抢购场景完全靠数据库来扛,压力是非常大的,我们在最近的一次抢购活动改版中,采用了redis队列+mysql事务控制的方案,画了个简单的流程图:

    QQ截图20141230150409

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

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

    举例:

    总库存: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(提交事务)
  • 相关阅读:
    ie firefox兼容性总结
    [软件推荐]Metalogix Migration Manager 3.1SharePoint第3方管理软件
    MOSS Query Tool
    sharepoint 特别信息 自个乐去吧~~
    我的迅雷资源博客已经开通!
    VS2007? 爱尝鲜的进来!
    IFrameWebPart For QuickPart 1.0 新鲜出炉,免费品尝,趁热哦~~
    用Mozilla Firefox做客户端,浏览OSS2007站点,兼容性评测!
    转载sharepoint相关资源
    QuickPart VS SmartPart
  • 原文地址:https://www.cnblogs.com/php5/p/4362244.html
Copyright © 2011-2022 走看看