2015-02-25 4 views
0

Я пытаюсь выполнить транзакционный запрос с использованием Yii 1.x - это должно в основном откат всех запросов, если есть проблема, могут ли люди подтвердить, что это правильный способ запуска транзакций с использованием Yii 1?Запуск транзакционных запросов в Yii 1.x

// data comes from a csv 
$transaction = Yii::app()->db->beginTransaction(); 
    try 
    { 

     if (($handle = fopen($path, "r")) !== false) { 
      while (($data = fgetcsv($handle)) !== FALSE) { 
       if ($currentRow == 1) { 
        $header = $this->import_fields(array_map('strtolower', $data)); 
        $currentRow++; 
        continue; 
       } else { 
        $data = array_combine($header, $data); 
        $csv_import_model = null; 

        if (!empty($data['username'])) { 
         $csv_import_model = StudentImportForm::model()->findByAttributes(array(
          'username' => $data['username'], 
          'organisation_id' => user()->data->organisation->getViewOrgId() 
         )); 
        } 

        if (is_null($csv_import_model)) { 
         $csv_import_model = new StudentImportForm(); 
         $isNew = true; 
        } else { 
         $isNew = false; 
        } 

        $csv_import_model->scenario = 'import'; 
        $csv_import_model->setAttributes($data); 
        $csv_import_model->unsetAttributes(array('password')); 

        if ($csv_import_model->validate()) { 

         if (in_array($csv_import_model->username, $processedUsername)) { 
          $csv_import_model->addError('username', sprintf('Duplicate username (%1$s) found in csv file. which may already exists on row number %2$s.', $csv_import_model->username, (array_search($csv_import_model->username, $processedUsername) + 1))); 
         } else { 

          if ($csv_import_model->save()) { 

           if ($isNew) { 
            $this->csv_results['inserted'] = $this->csv_results['inserted']+1; 
           } else { 
            $this->csv_results['updated'] = $this->csv_results['updated']+1; 
           } 

          } else { 
           $this->csv_results['error'][$currentRow] = $csv_import_model->getErrors(); 
          } 
         } 
        } else { 
         $csv_import_model->csv_index = $currentRow; 
         $this->csv_results['error'][$currentRow] = $csv_import_model->getErrors(); 
        } 

        $processedUsername[] = $csv_import_model->username; 

        $currentRow++; 
        Yii::getLogger()->flush(false); 
       } 
      } 
      fclose($handle); 
     } 

     $transaction->commit(); 
    } 
    catch(Exception $e) 
    { 
     $transaction->rollback(); 
    } 

ответ

2

$ model-> save() не создает исключения в случае его отказа. Он возвращает true или false. Чтобы откат всего блока, вы должны вручную выбросить исключение, если save() возвращает false. Попробуйте что-то вроде этого:

$errors = null; 
try { 
    if ($csv_import_model->save()) { 
     // continue with whatever logic you have 
     $transaction->commit(); 
    }else{ 
     $errors = 'Error when saving'; 
     throw new Exception('Could not save model'); 
    } 
}catch(Exception $e){ 
    //Do some logging here 
    $transaction->rollback(); 
    if($errors != null){ 
     Yii::app()->user->setFlash('error', $errors); 
    } 
} 
+0

где должна заключаться транзакция-> фиксация() в этом коде? – Zabs

+1

Я отредактировал свой ответ, чтобы поместить commit() в нужное место, сразу после сохранения(). Если у вас было больше сейвов, вы должны положить одну фиксацию в самом конце последнего сохранения. –

+0

Спасибо, что очень помогает - возможно ли записывать/сохранять строки моего csv, которые выбрали исключение для отображения в пределах сообщение флэш-сессии? – Zabs