Timer 定时任务中 数据乱掉了

yiqixing

问题描述

timer 定时任务中查询出订单列表,通过foreach 遍历每个订单,计算每个订单赠送的积分,设置的当赠送积分大于0时,进行积分变动,并记录,但实际运行时,积分记录表出现了很多score为0的记录;

$list 是订单列表
foreach ($list as $k=>$v){
            $good_list=$v['goods'];
            $score=0;
            foreach ($good_list as $k2=>$v2){
                $has_catgory=$good_category
                    ->where('goods_id',$v2['goods_id'])
                    ->where('category_id','in',$category_ids)
                    ->find();
                //满足商品属于指定分类,赠送积分
                if(!empty($has_catgory)){
                    $score=$score+$v2['total_num'];
                }
            }
            //积分大于0时执行,积分记录操作
            if($score>0){
                $uid=$v['user_id'];
                $data=[
                    'user_id' => $uid,
                    'value' => $score,
                    'describe' => "饮料订单赠送:{$v['order_no']}",
                    'store_id' => $v['store_id'],
                    'order_id' => $v['order_id'],
                ];

                $has_log=$this->where(['order_id' => $v['order_id']])->find();
                if(empty($has_log)){
                    $user->setIncPoints($uid,$score,$data['describe'],$v['store_id'],$v['order_id']);
                }

            }
        }
432 4 0
4个回答

yongdao35

业务逻辑问题,和框架定时器没关系

  • yiqixing 2023-10-20

    业务逻辑里面 我就加了判断积分大于0时,才进行积分操作的,但实际运行下来,数据库里有积分等于0的。而且我把函数拿出来单独运行是正常的,放到定时任务里面就出问题

  • luochen 2023-10-20

    是不是要设置成单进程的 $worker->count=1

  • TM 2023-10-21

    在定时里面每次都把积分写入日志看看几次定时任务的记录就知道了

  • TM 2023-10-21

    可以用一下 bcadd函数进行相加

xgdd1987

你这逻辑看着好难受。判断数据库中是否在某个记录,最好用select count(*),下面代码就可以用查询结果是否大于0来判断了。
你这样写,会有查询结果,结果还会封装成数组或对象,浪费服务器资源。

  • TM 2023-10-21

    感觉是出了精度问题,0.00001啥的 然后大于0

  • TM 2023-10-21

    他整条$good_category记录都查询出来了0.0

xgdd1987

双重循环里还有好几个查询数据库的逻辑,这样很不合理。
1、可以在循环开始前,就把订单中的商品的category_id查询出来。然后在循环中跟category_id做比对即可。
2、判断是否有没有赠送过积分,可以在订单中增加个状态字段来标识,在最初查询需要赠送积分的订单就进行过滤,这样就避免了每次都要查询积分记录表来判断。
3、$user->setIncPoints()赠送积分,可以先把要赠送的数据放到数组里,然后等循环结束后批量更新,这样只执行一次sql。(要注意同一个用户多个订单,积分要累加,逻辑上做个判断即可)
4、积分为0的问题,上面的代码没有看出来有什么积分计算bug,猜测很可能是在$user->setIncPoints()方法中出了问题,贴一下这个方法的代码吧。

  • 暂无评论
释永战

另外开启一个进程去进行数据库操作,定时器只负责定时触发任务执行···

  • 暂无评论
🔝