使用commit()时是否需要save()?

时间:2018-04-11 09:41:55

标签: php fat-free-framework

我意识到save()commit()将执行两次相同的数据库事务。

例如

if (isset($userId)) 
{
    $update = true;
    $user->load(array('id=:id', array(':id' => $userId)));
}

$user->designation_id = $f3->get('POST.designation_id');
$user->firstname = $f3->get('POST.firstname');
$user->lastname = $f3->get('POST.lastname');

$user->save(); //update made to users table

$this->db->begin();

foreach ($userTeams as $teamId) 
{
     $sqlArray[] = sprintf('INSERT INTO %s (internal_team_id, users_id) VALUES (%d,%d)', 'users_internal_team', $teamId, $user->get('_id'));
}
$this->db->exec($sqlArray); //update made to some other table

$this->db->commit();

echo $this->db->log();
die();

日志将显示"users"表中执行的以下事务:

...other log information related to other tables..

UPDATE `users` SET `designation_id`=3,`lastname`='Mali' WHERE `id`=134 Wed, 11 Apr 2018 11:39:20 +0200 (0.5ms) 
UPDATE `users` SET `designation_id`=3,`lastname`='Mali' WHERE `id`=134

这是否意味着我可以删除$user->save()$this->db->commit()会为我做同样的事情?

1 个答案:

答案 0 :(得分:1)

TL; DR

save()commit()是两回事,所以你不应该跳过save()

SQL背景

在SQL中,您可以编写:

UPDATE users SET designation_id=3,lastname='Mali' WHERE id=134;
INSERT INTO users_internal_team (internal_team_id, users_id) VALUES;(999,134)

或者你可以写:

BEGIN;
UPDATE users SET designation_id=3,lastname='Mali' WHERE id=134;
INSERT INTO users_internal_team (internal_team_id, users_id) VALUES;(999,134)
COMMIT;

不同之处在于,在第一个示例中,如果在INSERT语句期间发生错误(如重复条目),UPDATE语句将不会被取消(也称为“回滚”) ),而在第二个例子中它会。

在F3中,等效的例子是:

$db->exec('UPDATE users etc.');
$db->exec('INSERT INTO users_internal_team etc.');

$db->begin();
$db->exec('UPDATE users etc.');
$db->exec('INSERT INTO users_internal_team etc.');
$db->commit();

请注意,如果您将一组语句传递给exec()方法,它们将自动嵌入到事务中:

$db->exec([
  'UPDATE users etc.',
  'INSERT INTO users_internal_team etc.',
]);
// automatically calls $db->begin() and $db->commit()

您的代码

在您的代码中,您正在调用user->save(),这会触发$db->exec('INSERT etc.')$db->exec('UPDATE etc.'),具体取决于前一个$user->load()的结果。

这是一个声明。

当您跳过对$user->save()的调用时,日志中出现两个相同的语句且其中一个语句仍然显示,这一事实让我认为$sqlArray必须包含相同的语句。

我可能在后一点上错了,但无论如何,你使用的序列是正确的。