業(yè)務(wù)邏輯:用戶進行投票,投票之后寫入記錄;投票成功后更改用戶狀態(tài),不得再投票。直接通過postman測試接口是沒問題的,數(shù)據(jù)都正常。但是只要通過多進程腳本運行測試的話,寫入記錄會增多。目前想到的解決方案:使用redis有序集合,使用時間戳毫秒寫入獲取第一個再做對比。簡單來說,就是在毫秒維度進行做并發(fā)處理,但是感覺如果更高并發(fā)的話,應(yīng)該也會出問題。使用隊列服務(wù)處理。投票代碼:$uid=Token::getCurrentUid();$codeNum=Token::getCurrentTokenVar('codeNum');//并發(fā)處理$redis=Redis::getRedisConn();$key=RedisKeyNameLibrary::USER_VOTE.$codeNum;$score=array_sum(explode('',microtime()));$value=build_rand_str(32).':'.$uid;$redis->zRemRangeByScore($key,0,time()-1);//清除1秒前的集合$redis->zAdd($key,$score,$value);$zRangeArr=$redis->zRange($key,0,-1);if($zRangeArr[0]$value)returnreturnError('提交失敗,請重新提交!',30002);$tran=$this->db();$tran->startTrans();try{//根據(jù)ID獲取對應(yīng)模型$model=self::get($uid);$data=array_merge($model->toArray(),$data);//驗證$validate=newCodeValidate();$result=$validate->check($data,[],'vote');if(!$result)returnreturnError($validate->getError(),30001);$errorMsg=returnError('提交失敗,請重新提交!',30002);//更改為已投票$status=$model->data($data)->allowField(true)->save(['status'=>self::STATUS_1]);//保存成功后追加投票記錄if($status!==false){$saveData=[];$models=User::all(array_map('intval',$data['user_ids']))->all();foreach($modelsas$k=>$v)array_push($saveData,['code_num'=>$data['code_num'],'uid'=>$v->data['id'],'name'=>$v->data['name'],'group_id'=>$v->data['group_id']]);$model->logs()->saveAll($saveData);$tran->commit();returnreturnSuccess();}return$errorMsg;}catch(Exception$e){$tran->rollback();return$errorMsg;}以下是多進程測試投票接口的腳本:for($i=0;$i
萌新求教!PHP多進程提交時,數(shù)據(jù)重復(fù)插入。求大佬指點!
喵喵時光機
2019-08-21 19:01:10