zoukankan      html  css  js  c++  java
  • 【PHP】PHP代码处理(普通/不重要的)并发情况,例如pv统计(不使用MySQL行或表锁、避免程序冗余)

    1、PHP代码处理(普通/不重要的)并发情况,例如统计pv数据:什么意思呢?

    比如pv统计,某时间段pv数据不存在则新增,存在则更新+1,这时候会存在一个问题:我们查询的时候可能没有记录,但是准备插入的时候却已经有数据了(别的进程捷足先登)

    解决办法:我们可以在MySQL设置 唯一主键,配合php代码进行控制,使用 try catch 捕获MySQL的异常,匹配异常代码,将重复的一行进行更新

    /**
         * 页面pv统计
         */
        public function statPv(Request $request)
        {
            $node_id = $request->node_id ?? config('cache.master_node_id');
            $openId = $request->input('open_id');
            $event = Input::get('event') ?? '';
            $route = Input::get('route') ?? '';
            $data = S::show($route);
    
            if($event != 'show'){
                return S::jsonReturn( ['info'=>'fail~~'] );
            }
            $sessionKey = $request->input('3rd_session');
            if(empty($openId) || empty($sessionKey)){
                return S::jsonReturn( ['info'=>'fail'] );
            }
            $userInfo = unserialize(WeChatDao::baseRedis('get',  ':' . $openId . '_cache'));
            $sysSessionKey = unserialize(WeChatDao::baseRedis('get',  ':key:' . md5($sessionKey)));
            if(empty($sysSessionKey)){
                return S::jsonReturn( ['info'=>'fail~'] );
            }
            if(empty($userInfo)){
                return S::jsonReturn( ['info'=>'fail!'] );
            }
            if ($userInfo['open_id'] != $sysSessionKey['openid']) {
                return S::jsonReturn( ['info'=>'fail!!'] );
            }
    
            $url = $data['path'];
            $query = $data['query'];
            $trans_date = date('Y-m-d');
            $trans_hour = date('H') . ':00';
            
            $pvObj = StatPageVisitDay::where('node_id',$node_id)->where('trans_date',$trans_date)->where('trans_hour',$trans_hour)->where('url',$url)->first();
            if(!empty($pvObj)) {
                $pvObj->increment('pv');
            } else {
                $pvObj = new statPageVisitDay();
                $pvObj->node_id = $node_id;
                $pvObj->trans_date = $trans_date;
                $pvObj->trans_hour = $trans_hour;
                $pvObj->pv = 1;
                $pvObj->url = $url;
                $pvObj->param = $query;
                try {
                    $pvObj->save();
                } catch (Exception $e) {
                    $message = $e->getMessage();
                    if (strstr($message, "Duplicate") && strstr($message, "for key ")) {
                        log_write('插入pv表主键或唯一索引重复,再次执行更新操作' . $message);
                        StatPageVisitDay::where('node_id',$node_id)->where('trans_date',$trans_date)->where('trans_hour',$trans_hour)->where('url',$url)->increment('pv');
                    } else {
                        log_write("PV入库异常,原因{$e->getMessage()}");
                        MailDao::warning("pv统计异常. 页面uri={$route},", json_encode(['err_msg'=>$e->getMessage()]));
                        return S::jsonReturn( ['info'=>'statpv insert failed'] );
                    }
                }
            }
    
            return S::jsonReturn( ['info'=>'success'] );
        }
  • 相关阅读:
    HTML5 video标签支持情况分析
    1px直线与1px四边边框的写法
    FJOI2017 day2游记
    FJOI2017前做题记录
    关于Fibonacci博弈的一些学习
    【BZOJ4195】 [Noi2015]程序自动分析
    【BZOJ2115】 [Wc2011] Xor
    【BZOJ3811/UOJ36】 玛里苟斯
    【BZOJ4565】 [Haoi2016]字符合并
    【BZOJ2749】[HAOI2012]外星人
  • 原文地址:https://www.cnblogs.com/xuzhengzong/p/13947254.html
Copyright © 2011-2022 走看看