如何在Yii中保存数据并确保正确保存?

时间:2015-10-07 10:49:24

标签: php yii orm

示例:我们有测试表,它有3列:id,watchers,title。 我们有一个代码:

$test = Test::model()->findByPk(1);
echo $test->watchers; // 0
$test->title = 'another';
$test->save();

当我们调用save()时,ir会生成像"UPDATE test SET title='another', watchers='0' WHERE id='1'"这样的SQL查询。所以,一切都很好。但问题是,如果另一个进程将在findByPk之间的时间内更新观察者变量并保存在当前脚本中,则代码将生成错误的值。所以:

$test = Test::model()->findByPk(1);
echo $test->watchers; // 0
$test->title = 'another';
//HERE WE HAVE A CODE WHICH PERFORMS FOR 1 SECOND. MEANWHILE ANOTHER PROCESS
// UPDATES TABLE WITH WATCHERS = 1
$test->save();

所以,这段代码会将记录的观察者字段保存回0.如何克服这个问题?为什么Yii ORM不保存更改的值?为什么它试图保存所有值?谢谢。

3 个答案:

答案 0 :(得分:2)

由于您获得$test中的每个值,因此当您执行$test->save();时,每个属性都会使用新记录或其包含的先前值保存。

当您查询$test = Test::model()->findByPk(1);时,$test->watchers;将与您执行查询时的值相同,此值只会更改(如果观察者的值已被另一个{{1}更改} query,当你做另一个update查询时。希望有道理:P

您可以尝试以下更新方法:

select

将执行以下查询:

Test::model()->updateByPk(1, array(
                'title' => 'another'
            ));

答案 1 :(得分:1)

我会解决这个问题:

$test = Test::model()->findByPk(1);
$test->title = 'another';

/*according to the api the second parameter only saves the columns 
  that are mentioned in the array. In this case it will save just the
  title
*/

$test->save(true,array('title')); 

<强> {或}

 $test = Test::model()->findByPk(1);
    $test->title = 'another';

    /*according to the api the parameter only saves the columns 
      that are mentioned in the array. In this case it will save just the
      title
    */

    $test->saveAttributes(array('title')); 

答案 2 :(得分:0)

对我来说,最好的解决方案是继承和重写save()方法,并将其行为与Yii2(getDirtyAttributes()方法)中的行为相同。 W必须比较从db属性获取的属性并仅保存那些已修改的属性。我已成功实施此功能,并可确认其有效。