跟老姚学前端,课程体系更完善,10%基础 + 90%实战演练,快人一步学编程

扫一扫浏览

教你如果处理高并发数据不同步的问题php篇

未结贴
0 9272
鸿老大站长未认证 2017-12-14 14:30:21
收藏

现在做商城这么多,但大部分都是用的开源商城,但公司可能会一些抢购的活动,当然,不出问题你什么问题都发现不了,毕业流量还没有达到那么大,但一旦流量达到足够大的时候,并发就很有可能发生,这个时候你的商品抢购数量就有可能出问题,100件的商品,最后成功订单可能出现105个 ,下面我们来模拟一下这种情况。

公共连接数据库部分

第一种:正常代码的情况

先自己创建一个t_goods数据库,其中库存字段为stock,看代码

代码的功能很简单,就是每运行一次就去把库存减一,你如果在浏览器里面刷新,肯定没问题,因为这不是并发,你可以模拟一下并发的情况,我这里默认库存为100,模仿10个用户同时发10个请求的情况,看库存会减多少?

看结果,库存才减6,这就是并发出现库存不同步的问题

问题是怎么出现的呢?

A去查询库存(假如是100),正要减一(没来得及减),B也去查询库存(肯定为100),A去减一了,B也去减一(减的是自己查询到的100), 最后两个操作后,库存还为99,正常应该为98才行,这就是并发出现的问题,那怎么解决呢,下面我介绍四种加锁的解决方案,数据库锁、文件锁、Memcache锁、Redis锁

第一种加锁:数据库锁

这种锁不建议使用,因为它会锁库,其它人可能就动不了库了,流量比较大的情况,网站可能就会崩

第二种加锁:文件锁

注意:文件锁也分为排它锁(LOCK_EX)和共享(LOCK_SH)锁两种,这里只能用排它锁

第三种锁:Memcache锁

要用到Memcache锁,首先你的服务器要安装Memcache的支持

class MemcacheLock
{
    public function __construct($options=null)
    {
        $this->memcache = new Memcache();
        $this->memcache->connect("127.0.0.1", 11211);
    }

    public function getLock($key, $timeout=5)
    {     
        $waitime = 20000;
        $totalWaitime = 0;
        $time = $timeout*1000000;
        while ($totalWaitime < $time && false == $this->memcache->add($key, 1, false ,$timeout)) 
        {
            usleep($waitime);
            $totalWaitime += $waitime;
        }
        if ($totalWaitime >= $time)
            throw new Exception('can not get lock for waiting '.$timeout.'s.');

    }

    public function releaseLock($key)
    {
        $this->memcache->delete($key);
    }
}

第四种锁:Redis锁

class RedisLock
{
	private $_redis=null;

	public function __construct($config=null){
		$this->_redis = $this->_redis == null ? new redis() : $this->_redis;
        $this->_redis->connect($config);
	}

    public function getlock($key, $expire = 60)
    {
        if(!$key) {
            return false;
        }
        do {
            if($acquired = ($this->_redis->setnx("Lock:{$key}", time()))) { // 如果redis不存在,则成功
                $this->_redis->expire($key, $expire);
                break;
            }

            usleep($expire);

        } while (true);

        return true;
    }

    //释放锁
    public function releaseLock($key)
    {
        $this->_redis->del("Lock:{$key}");
        $this->_redis->close();
    }
}

ok,这些只是给你的一些方案,可能还有一些其它的方案来处理并发数据同步的问题,在实际项目中自己合理去抉择,选择自己合适的方案。有问题留言....

原创出处:http://noob.d8jd.com/fine/view/55880

最近热帖 HOT TOPIC
【全套视频】thinkphp5视频教程 92884
父元素flex之后,子元素高度自适应问题 11292
一张纸的厚度是0.01毫米,则该纸对折30次后是多厚(据说超过珠穆朗玛峰的高度)php实现 10541
thinkphp5隐藏默认模块的一些问题 10010
api接口文档插件easydoc的基本用法,快速搞定接口文档 9792
如何收废品才能赚钱,有什么技巧?揭秘垃圾回收行业的一些规则 9729
PHP如何判断字符串是否为json格式 9633
omnicore rpc api中文手册【usdt】 9552
教你如果处理高并发数据不同步的问题php篇 9273
关于thinkphp5.0.x getshell漏洞的说明 9182
月度热议HOT COMMENTS
【全套视频】thinkphp5视频教程 75
tpframe 后续版本你希望有的功能是什么(分享贴) 12
权限那里怎么一登录别的账号就报错啊 9
关于tpframe的一点话题 6
cms插件在分类排序的时候JSON错误 6
基于tpframe v3.x 的微信公众号插件已批量上线 5
tpframe插件tcms插件v2.2已发布上线,欢迎下载使用 5
tpframe6.0马上就要跟大家见面了,一次全新的升级 5
透析thinkphp5升级版开发框架tpframe 3
新增的管理员没有权限操作CMS模块。 3
爆料早知道: