Сначала SELECT
, чтобы узнать, нужно ли INSERT
или UPDATE
, например:
if (
$db->fetchOne(
'SELECT COUNT(1) FROM parts WHERE article_number = ?',
$p->article_number
)
) {
$db->update(
'parts',
$p->to_array(),
$db->quoteInto('article_number = ?', $p->article_number)
);
}
else {
$db->insert('parts', $p->to_array());
}
Комментарий Ре Милена: отличный момент! При уровне изоляции транзакций PostgreSQL по умолчанию (READ COMMITTED
) возможно, что другой процесс вставит (и подтвердит) "вашу" часть после вашей SELECT
, но до вашей INSERT
.
Для приложений, которые мы создаем, мы обычно просто перехватываем исключение из БД и что-то предпринимаем (сообщите пользователю, повторите попытку). Или вы можете пойти с SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
. См. Изоляция транзакции .