2017-12-04 14 views
0

私のコードでトランザクションを実装しようとしています。しかし、モデル($タイムシートモデル)トランザクションの1つの検証に失敗しても、ロールバックは行われません。以下 は私のコードです:yii2トランザクションはロールバックされません

public function actionCreate() { 
    $model = new Timesheet(); 
    $subscriber = null; 
    // get current subscriber id. 
    $subscriber_id = General::getSubscriberIdByUserId(\Yii::$app->user->id); 
    if ($subscriber_id > 0) { 
     $subscriber = Subscriber::findOne($subscriber_id); 
     if ($subscriber) { 
      $model->subscriber_id = $subscriber->id; 
      $model->subscriber_name = $subscriber->name; 
     } 
    } 

    if ($model->load(Yii::$app->request->post())) { 

     //Transaction starts here 
     $transaction = Yii::$app->db->beginTransaction(); 
     try 
     { 
      if (!empty($model->date)) { 
       $model->date = General::convertDDMMYYYYToMysqlCompliant($model->date); 
       $model->user_id = \Yii::$app->user->id; 
      } 

      // to find total hours of the day already logged    
      $total_daily_hours = (Timesheet::find()->where(['user_id' => Yii::$app->user->id])->andWhere(['date' => $model->date])->sum('hours')); 

      $model->hours = ($model->hours + $model->minute); 
      $dayofweek = date('w', strtotime($model->date)); 
      if($dayofweek == 6) 
      { 
       $monday = date('Y-m-d', strtotime('last monday', strtotime($model->date))); 
      } 
      else 
      { 
       $monday = date('Y-m-d', strtotime('this monday', strtotime($model->date))); 
      } 
      $saturday = date('Y-m-d', strtotime('this saturday', strtotime($model->date))); 

      // to find total hours of the week already logged 
      $team_member_weekly_hours = Timesheet::find()->where(['user_id' => \Yii::$app->user->id])->andWhere(['between', 'date', $monday, $saturday])->sum('hours'); 

      $role = \Yii::$app->authManager->getRolesByUser(\Yii::$app->user->id); 

      if(array_key_exists('intern', $role) == false) 
      { 
       $TEAM_MEMBER_WEEK_LIMIT = 48; 
      } 
      else 
      { 
       $TEAM_MEMBER_WEEK_LIMIT = Timesheet::TEAM_MEMBER_WEEK_LIMIT; 
      } 

      if ((
        (Timesheet::PER_DAY_HOURS_LIMIT) >= ($total_daily_hours + $model->hours) 
        || ((Timesheet::PER_DAY_HOURS_LIMIT) >= ($total_daily_hours + $model->hours) 
         && (array_key_exists('team-member', $role))) 
       ) 
       && (Timesheet::blockMonthEntry($model->date) == true) 
       && ($TEAM_MEMBER_WEEK_LIMIT >= $team_member_weekly_hours + $model->hours) 
       && ($model->hours != 0)) 
      { 
       // get user hourly rate 
       $usertohourlyrate = UserToHourlyRate::getHourlyRateByUserId($model->user_id); 
       $model->total_amount = $usertohourlyrate * $model->hours; 
       $model->hourly_rate = $usertohourlyrate; 

       // echo "<pre>";var_dump($model);die; 

       if($model->save()) 
       { 
        $model_id = $model->id; 
       } 
       // echo "$model_id"; 

       //For Notification 
       $userToNotify = []; 
       $user_id = \Yii::$app->user->id; 
       $userForNotify = UserToSubscriber::find()->select('senior_user_id')->where(['user_id'=>$user_id])->all(); 

       if($userForNotify != NULL) 
       {      
        $userToNotify = []; 
        foreach($userForNotify as $ufn){ 
         array_push($userToNotify,$ufn->senior_user_id); 
        } 

        foreach($userToNotify as $value) 
        {       
         $noticemodel = new Notifications(); 
         $noticemodel->user_id = $value; 
         $noticemodel->relation_name = 'timesheet'; 
         $noticemodel->relation_id = $model->id; 
         $noticemodel->notice_abstract = "Timesheet Created Notification."; 
         $noticemodel->action = '0'; 
         $noticemodel->created_on = date('Y-m-d h:i:s');        
         $noticemodel->save(); 
        } 
       } 
       // 

       if (General::ifUserPermitted('timesheetAutoTimesheetApproval')) { 
        // echo "in if"; 
        // timesheet auto approval 
        // WIP update 
        General::onTimesheetChange($model->job_id, $model->user_id, $model->date, "timesheet"); 
        //For update timesheet model 
        $timesheet_model = Timesheet::findOne($model_id); 
        echo "<pre>";var_dump($timesheet_model);//die; 
        $timesheet_model->action_taken_at = date("Y-m-d h:m:s"); 
        $timesheet_model->action_taken_by = \Yii::$app->user->id; 
        $timesheet_model->status = "Approved"; 
        echo "<pre>";var_dump($timesheet_model);     
        $timesheet_model->save(); 
        if($timesheet_model->save()) 
        { 
         echo "True"; 
        } 
        else 
        { 
         echo "False"; 
         $errors = $timesheet_model->errors; 
         echo "<pre>";var_dump($errors); 
        } 
        //For Notification 
        if($userForNotify != NULL) 
        { 
         $userToNotify = []; 
         foreach($userForNotify as $ufn){ 
          array_push($userToNotify,$ufn->senior_user_id); 
         } 

         foreach($userToNotify as $value) 
         { 
          $notification = Notifications::find()->where(['user_id'=>$value , 'relation_id'=>$model->id, 'notice_abstract'=>'Timesheet Created Notification.'])->one(); 
          if($notification != NULL) 
          { 
           $notification->action = '1'; 
           $notification->save();    
          } 
         } 
        }      
        // 
       } 
       if (array_key_exists('team-member', $role)) { 
        $msg = "Entry Inserted Successfully and Your remaining weekly hours is <b>" . ((Timesheet::TEAM_MEMBER_WEEK_LIMIT) - ($team_member_weekly_hours + $model->hours)) . " hrs.</b>"; 
       } else { 
        $msg = "Entry Inserted Successfully and Your remaining hours is <b>" . ((Timesheet::PER_DAY_HOURS_LIMIT) - ($totel_hours + $model->hours)) . " hrs.</b>"; 
       } 
       \Yii::$app->session->setFlash('success', $msg); 

       $transaction->commit(); 

       return $this->redirect(['view', 'id' => $model->id]); 

      } 
      elseif (Timesheet::blockMonthEntry($model->date) != true) { 
       $msg = "This date has been blocked"; 
      }elseif ($totel_hours == (Timesheet::PER_DAY_HOURS_LIMIT) || $team_member_weekly_hours == (Timesheet::TEAM_MEMBER_WEEK_LIMIT)) {     
       $msg = "Your Daily hours is over"; 
      } elseif (($totel_hours + $model->hours) > Timesheet::PER_DAY_HOURS_LIMIT) { 
       $msg = "Your remaining daily hours only is <b>" . ((Timesheet::PER_DAY_HOURS_LIMIT) - $totel_hours) . " hrs.</b>"; 
      } elseif ($model->hours == 0) { 
       $msg = "Please select hours"; 
      } else { 
       $msg = "Your remaining Weekly hours only is <b>" . ((Timesheet::TEAM_MEMBER_WEEK_LIMIT) - $team_member_weekly_hours) . " hrs.</b>"; 
      } 
      \Yii::$app->session->setFlash('error', $msg); 
      list($model->hours, $minute) = explode('.', $model->hours); 
      $model->minute = "0." . $minute; 

      if(empty($model->date)){ 
       $model->date = date('j/n/Y'); 
      }else{ 
       $model->date = General::convertMysqlDateToDDMMYYYY($model->date); 
      } 
      return $this->render('create', [ 
         'model' => $model, 
         'master_mode' => Yii::$app->user->can('associateSubscriberWithDetails'), 
      ]); 
     } 
     catch(Exception $e) 
     { 
      \Yii::$app->session->setFlash('error', $e); 
      $transaction->rollBack(); 
     } 
     //Transaction ends here 
    } 
    else 
    { 
     if(empty($model->date)){ 
      $model->date = date('j/n/Y'); 
     }else{ 
      $model->date = General::convertMysqlDateToDDMMYYYY($model->date); 
     } 

     return $this->render('create', [ 
        'model' => $model, 
        'master_mode' => Yii::$app->user->can('associateSubscriberWithDetails'), 
     ]); 
    } 
} 

私は何をすべき?コードを修正する場所は? モデルを更新中にタイムシートモデルが失敗しましたが、モデルはロールバックされません。

モデルsave()のいずれかが失敗した場合、save()をすべてロールバックします。

+0

をMySQLのテーブルengingeをチェックしてください。それはInnodbでなければなりません。 「MyIsam」はトランザクションをサポートしていません – smoqadam

+1

質問です - なぜロールバックする必要がありますか?あなたは例外を投げているわけではなく、 '$ model-> save()'もそれをやっていません。 – Yupik

+0

多くのコードは、コントローラではなくモデルに配置する方がよいでしょう。 – pat

答えて

0

Yii save()このメソッドの実行が失敗した場合(Exceptionの場合)は例外をスローしません。したがって、あなたはsave()の結果をチェックし、失敗した場合に例外をスローする必要があります。

あなたにここに使用し、あなたのtry{}catch(Exception $e){}文でsave()を使用します。

if (!$model->save()) { 
    throw new Exception("Trigger transaction rollback"); 
} else { 
    // something 
} 
関連する問題