【问题标题】:Run transaction queries in Yii 1.x在 Yii 1.x 中运行事务查询
【发布时间】:2015-02-25 13:58:10
【问题描述】:

我正在尝试使用 Yii 1.x 运行事务查询 - 如果出现问题,这基本上应该回滚所有查询,人们可以确认这是使用 Yii 1 运行事务的正确方法吗?

// 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();
    }

【问题讨论】:

    标签: php yii transactions


    【解决方案1】:

    $model->save() 在失败时不会抛出异常。它返回真或假。为了回滚整个块,如果 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);
       }
    }
    

    【讨论】:

    • transaction->commit() 在这段代码中应该放在哪里?
    • 我编辑了我的答案,将 commit() 放在正确的地方,就在 save() 之后。如果你有更多的保存,你应该在最后一次保存的最后放置一个提交
    • 谢谢,这真的很有帮助 - 是否可以记录/保存我的 csv 中引发异常的行以显示在 Flash 会话消息中?
    • 是的。我再次编辑了我的答案。只需确保您有一个变量来存储 try-catch 块之外的错误消息并向其中添加任何错误消息(有关详细的错误消息处理,请参阅文档:yiiframework.com/doc/api/1.1/CModel#getErrors-detail")。
    猜你喜欢
    • 1970-01-01
    • 2016-01-25
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-04
    • 2017-03-15
    • 1970-01-01
    相关资源
    最近更新 更多