Strange error message

Hi guys,

I have several records in my table.If I will update records, I will get sometimes, not always, error like this




 The object being updated is outdated. in E:\xampp\htdocs\yii2_perswitch\vendor\yiisoft\yii2\db\BaseActiveRecord.php



Following code in framework is responsible for this error





 	if ($lock !== null && !$rows) {

            throw new StaleObjectException('The object being updated is outdated.');

        }



I assume something is wrong with optimistiLock. As it’s definetly no solution changing code in framework,I’d glad to get feedback. How can this error be avoided changing my code, not code of framework?

Source code can be found here

Try a delete method using dbo or querybuilder, that may work.

Why should I use a delete-method

I want to update, not delete. So, I use




...


        $model->save();

        $model_person->save();

...



in Controller

As long I get no answer, which will bring clarity, I decided to remove optimistic lock attribute of model.Now, everything is all right, apart from circumstance, I have no value for optimistic lock any more…

Think on your feet, I accidentally typed delete instead of update. Whatever add, create, update…

The optimistic locking of Acitve Record SHOULD WORK as expected for you, since it IS WORKING as expected for many yii developers.The chances are, as you are aware of, some error in your code was causing an unexpected StaleObjectException.

For example, this will cause a StaleObjectException:




$model_a = Person::findOne(1);

$model_a->name = "foo";

...

$model_b = Person::findOne(1);

$model_b->name = "bar";

$model_b->save(); // OK

...

$model_a->save(); // StaleObjectException



Removing optimistic lock attribute from Person may prevent throwing StaleObjectException, but the error in this code is still alive and will cause another unexpected result.

jimgwhit2

It is YOU that wrote "delete" instead of "update", not @tklustig.

So, it’s me to correct code,isn’t it? Following code in controller obviously 'causes error. But there are not statetments compared with ur example above





    public function actionUpdate($id) {

        try {

            $behavior = new \common\wsl_components\Wsl_Blameable_Behavior();

            $aktualisiert_von = $behavior->get_User_Person_Id();

            $model = $this->findModel($id);

            $model->scenario = 'update';

            $model_person = $this->findModel_person($model->id_person);

            $model_person->scenario = 'update';

            if (!$model || !$model_person) {

                throw new NotFoundHttpException("Bitte überprüfen Sie die Validiatät der Tabellen bewerber bzw. person");

            }

            $model->aktualisiert_von = $aktualisiert_von;

            $model_person->aktualisiert_von = $aktualisiert_von;

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

                $valid = $model->validate();

                $isValid = $model_person->validate();

                $isValid = $valid & $isValid;

                if ($isValid) {

                    $model->avatar = UploadedFile::getInstances($model, 'avatar');

                    $model->upload();

                    $model->save();

                    $model_person->save();

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

                } else {

                    $error_bewerber = $model->getErrors();

                    $error_person = $model_person->getErrors();

                    foreach ($error_person as $values) {

                        foreach ($values as $ausgabe) {

                            echo"<p>" . $ausgabe . "</p>";

                        }

                    }

                    foreach ($error_bewerber as $values) {

                        foreach ($values as $ausgabe) {

                            echo"<p>" . $ausgabe . "</p>";

                        }

                    }

                    echo Growl::widget([

                        'type' => Growl::TYPE_DANGER,

                        'title' => 'Oh snap!',

                        'icon' => 'glyphicon glyphicon-remove-sign',

                        'body' => 'Aus unbekannten Gründen konnten die Tabellen nicht validiert werden<br>Bitte informieren Sie den Hersteller gemäß obiger Angaben!',

                        'showSeparator' => true,

                        'delay' => false,

                        'pluginOptions' => [

                            'showProgressbar' => true,

                            'placement' => [

                                'from' => 'top',

                                'align' => 'right',

                            ]

                        ]

                    ]);

                    return $this->render('update', [

                                'model_person' => $model_person,

                                'model' => $model

                    ]);

                }

                //solange noch kein Submittbutton gepusht

            } else {

                return $this->render('update', [

                            'model_person' => $model_person,

                            'model' => $model

                ]);

            }

        } catch (\Exception $error) { //fange den schweren MySQL-Fehler ab

            $go_back = "bewerber";

            \common\wsl_components\error_handling::error($error, $go_back);

        }

    }



I reintegrated optimistc_lock attribute to model. Furthermore, I changed code likte this:


    $model_person = $this->findModel_person($model->id_person);

to this:


    $model_person=Person::findOne($model->id_person);

Now, error seems to be disapeared. I have no ideas, why, but it seems to work…

Do you remember that you were using "saveAll" at first? You wrote something like this:




$model = Parent::find()->with('child')->where(['id' => xxx])->one();

$model_child = Child::findOne($model->child_id);

$model->child->name = "Foo";

$model->saveAll(); // OK

$model_child->name = "Bar";

$model_child->save();  // StaleObjectException



This could generate the StaleObjectException, because you are trying to save child record twice.

Note that "saveAll" saves the parent and the related child. It is roughly equivalent to the following:




$model->child->save();

$model->child_id = $model->child->id;

$model->save();



Okay. Thx for this general informations. I will distiguish two methods save and saveall() in future more strictly…