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(提交事务)
  • 相关阅读:
    远程登陆服务——SSH
    A web-based 3D modeling framework for a runner-gate design( 一种基于web的三维建模框架)
    Vue+Element+Echarts+Springboot+微信小程序开发(肿瘤医学项目)
    基于拖放布局的 Twitter Bootstrap 网站生成器
    Ubuntu下git使用华为云/gitee/github
    在 Ubuntu 18.04 上安装 Postman
    在Ubuntu 18.04上安装Git与入门教程
    转载:渲染层和逻辑层
    Ubuntu系统中安装Neo4j
    NosqlBooster连接数据库失败connect ECONNREFUSED 127.0.0.1:27017——mongodb连接失败
  • 原文地址:https://www.cnblogs.com/php5/p/4362244.html
Copyright © 2011-2022 走看看