0

我有一个奇怪的情况。假设我在 php 中有一个非常简单的函数(我使用了 Yii,但问题很普遍),它在事务语句中被调用:

public function checkAndInsert($someKey)
{
   $data = MyModel::model()->find(array('someKey'=>$someKey)); // search a record in the DB.If it does not exist, insert
   if ( $data == null)
   {
     $data->someCol = 'newOne';
     $data->save();
   }
   else
   {
     $data->someCol = 'test';
     $data->save();  
   }

}
...
// $db is the instance variable used for operation on the DB
$db->transaction();
$this->checkAdnInsert();
$db->commit();

也就是说,如果我通过盯着许多进程来运行包含此函数的脚本,我将在数据库中有重复的值。例如,如果我有 $someKey='pippo',并且我通过启动 2 个进程来运行脚本,我将有两个(或更多)列“someCol”=“newOne”的记录。这是随机发生的,并非总是如此。代码错了吗?我应该以 KEY 的形式在 DB 中设置一些约束吗?我还阅读了这篇关于向 TokuDB 添加 UNIQUE 索引的帖子,其中说 UNIQUE KEY “杀死”了写入性能......

4

1 回答 1

1

你的方法是错误的。这是错误的,因为您将完整性/唯一性检查的权限委托给 PHP,但它是负责执行此操作的数据库。

换句话说,您不必检查某些东西是否存在然后插入。这很糟糕,因为 PHP 和 MySQL 之间总是存在一些轻微的 ping,并且正如您已经看到的那样 - 您的检查可能会得到错误的结果。

如果您需要特定列或列组合的唯一值,请添加UNIQUE约束。之后,您只需插入。如果记录存在,则插入失败,您可以通过Exception. 它不仅更快,而且对您来说也更容易,因为您的代码可以成为更容易维护或理解的单行代码。

于 2015-01-03T11:40:14.200 回答