请教高手像这样的复杂的循环逻辑处理程序中如何使用事务

194 阅读2分钟
$students = I('students');
$content = filterEmoji(I('content'));
$is_v = I('is_v');
$video_id = intval(I('video_id'));
$xktime = I('xktime');
$class_id = intval(I('class_id'));
$activity_id = intval(I('activity_id'));
$files=$_FILES['file']['name'];

$_result = M('classroom')->where('class_id='.$class_id)->find();  

$class_activity = M('class_activity');
$map['activity_id'] = array('eq', $activity_id);
$act_result = $class_activity->where($map)->find();

$class_activity_video = M('class_activity_video');
$class_act_history = M('class_activity_history');
$s_map['teacher_id'] = array('eq', $teacher_id);
$s_map['classroom_id'] = array('eq', $act_result['classroom_id']);
$s_map['activity_id'] = array('eq', $activity_id);
$results = $class_act_history->where($s_map)->find();

if($results['create_time']+60*30 > time()){
   $data=array('result'=>NULL,'code'=>0,'message'=>'请不要重复提交此活动,请到历史活动中看看。
   如果有其他学员上此活动请于半小时后再尝试!');
} else {
    $info['status'] = 2;
    $info['isorder'] = 1;
    $info['content'] = $content;
    $info['update_time'] = time();
    $res = $class_activity->where($map)->save($info);
    //这里是一个班级的活动内容上完了。更新下内容并把状态恢复成原来的。下次有可能继续上,但上的学生是不同。
    if($res !== false) {
        M()->startTrans();
        $xktime = $xktime != '' ? strtotime($xktime) : time();
        //这个表是老师给所有学生上课知识点掌握情况的记录。
        一节课可能有5个知识点,然后一个学生就针对5个知识点有5条记录的评分。10个学生就有50条记录。
        $activity_reward = M('class_activity_student');
        $e_map['teacher_id'] = array('eq', $teacher_id);
        $e_map['classroom_id'] = array('eq', $act_result['classroom_id']);
        $e_map['activity_id'] = array('eq', $activity_id);
        $e_map['history_id'] = array('eq', 0);
        $_users = $activity_reward->where($e_map)->group('user_id')->select();
        //这里是根据老师班级课程内容查找出来所有的上课学生。

        $tags['video_id'] = $video_id;
        $tags['activity_id'] = $activity_id;
        $tags['course_actid'] = $act_result['course_actid'];
        $tags['classroom_id'] = $act_result['classroom_id'];
        $tags['course_id'] = $act_result['course_id'];
        $tags['teacher_id'] = $teacher_id;
        $tags['stage_id'] = $act_result['stage_id'];
        $tags['title'] = $act_result['title'];
        $tags['intro'] = $act_result['intro'];
        $tags['student'] = count($_users); // 有多少学生上课。
        $tags['hour'] = $_result['course_hour'];
        $tags['intro'] = $act_result['intro'];
        $tags['content'] = $content;
        $tags['create_time'] = $xktime;
        $tags['up_time'] = time();
        $history = $class_act_history->add($tags);
        //这些是把这节课上的内容记录下来为学生或老师以后查看。
        if($history){
            $member = M('member');  学生表
            $member_area = M('member_area');  学生课时表
            $member_record = M('member_record');  学生上课记录表

            $user_p_ary = array();
            $_record['classroom_id'] = $class_id;
            $_record['agency_id'] = $_result['agency_id'];
            $_record['area_id'] = $_result['area_id'];
            $_record['activity_id'] = $activity_id;
            $_record['history_id'] = $history;
            $_record['create_time'] = time();
            //这里就是循环所有的学生
            foreach ($_users as $key => $v) {
                array_push($user_p_ary, $v['user_id']);
                $_record['user_id'] = $v['user_id'];
                $_record['hour'] = $_result['course_hour'];
                $member_record->add($_record);
                //然后把某学生上的多少课时添加,生成课时记录。
                
                $user_area['user_id&area_id'] = array($v['user_id'],$_result['area_id'], '_multi'=>true);
                $member_area->where($user_area)->setDec('area_time',$_result['course_hour']);
                // 这里是把某个学生的课时表要减课时。
               
                $_score['user_id&classroom_id&activity_id&history_id'] = array($v['user_id'],$act_result['classroom_id'], $activity_id, $history,'_multi'=>true);
                $avgScore =    $activity_reward->where($_score)->avg('score');
                if($avgScore){
                    $member->where('Uaid='.$v['user_id'])->setInc('score', round($avgScore));
                    //这里是给上课的学生取老师知识点评分平均值去加积分值。
                }
            }

            $_lists = $activity_reward->where($e_map)->select();
            foreach ($_lists as $k => $v) {
                $_word = array('history_id'=>$history);
                $activity_reward->where('student_id='.$v['student_id'].'')->setField($_word);
                //这里要把这个学生上课时的所有评分项的历史记录ID更新下。
                因为老师是先上课, 在上课的过程中去给每一个学生知识点打分,
                先有的这个知识点打分记录。然后上完课才开始把照片以及课程上的内容
                给提交。提交之后才有的这个一条历史记录ID,所以要把上课时的所有
                关联记录都要给这个历史记录唯一ID关联更新上。
            }
            $user_ary = implode(',',$user_p_ary);

            $photo = M('class_activity_photo');

            if(count($files) > 0) {   // 如果有图片上传,处理到一个表中。有班级ID,活动ID
                $setting=C('UPLOAD_TEACHER_QINIU');
                $Upload = new \Think\Upload($setting);
                $Upload->allowExts  = array('jpg', 'mp4', 'gif', 'png', 'jpeg');// 设置附件上传类型
                $Upload->savePath =  'tp';// 设置附件上传目录
                $info = $Upload->upload($_FILES);
                foreach ($info as $k => $v) {
                    $_data['type'] = 0;
                    $_data['isqn'] = 1;
                    $_data['classroom_id'] = $class_id;
                    $_data['activity_id'] = $activity_id;
                    $_data['history_id'] = $history;
                    $_data['user_ary'] = $user_ary;
                    $_data['url'] = 'tp_'.$info[$k]['savename'];
                    $_data['create_time'] = time();
                    $photo->add($_data);
                }
                这里就是把照片上传掉。照片是全班的整体上传的多张照片,照片不需要与学生单独关联。
            }
            $data=array('result'=>$history,'code'=>1,'message'=>'success');
            M()->commit();
        }
    } else {
        M()->rollback();
        $data=array('result'=>NULL,'code'=>0,'message'=>'数据保存异常,请刷新重试一下');
    }
}

如上复杂的程序逻辑处理中。如何使用事务,就是要处理四五张表数据而且大多都是循环,有更新有添加。求大神指点。