firstOrCreate() vs createOrFirst()

Источник: «firstOrCreate() vs createOrFirst()»
В Laravel v10.20 появился совершенно новый метод createOrFirst(), созданный Tony Messias, который может вызвать некоторое недоумение, поскольку в Laravel уже был метод firstOrCreate(). В чем же заключаются различия? Зачем нам нужны два метода? Давайте посмотрим...

createOrFirst()

Новый метод createOrFirst() предназначен для более эффективной работы в высоко параллельных средах и помогает уменьшить количество гонок, но требует уникального ограничения на базу данных.

В случае createOrFirst мы инвертируем этот поток и полагаемся на то, что таблицы имеют ограничение UNIQUE. Таким образом, сначала мы пытаемся создать запись, а если получаем от базы данных исключение и определяем, что это нарушение ограничения уникальности, то вместо этого пытаемся найти соответствующую запись. Таким образом, параллельные процессы могут полагаться на ACID-характеристики базы данных и больше не беспокоиться о возникновении условий гонки.

Более подробную информацию можно найти в pull request.

firstOrCreate()

firstOrCreate был первоначальным методом, и вот как он определён в документах в настоящее время:

Метод firstOrCreate попытается найти запись в базе данных по заданным парам столбец/значение. Если модель не удаётся найти в базе данных, то будет вставлена запись с атрибутами, полученными в результате объединения первого аргумента массива со вторым необязательным аргументом массива.

Новый метод хорош ещё и тем, что теперь оригинальный метод firstOrCreate использует под капотом новый метод createOrFirst. Таким образом, он работает следующим образом:

  1. Пытается найти.
  2. Если отсутствует, попытка создания.
  3. Если происходит нарушение UNIQUE, то делается ещё одна попытка найти, так как мы столкнулись с условием гонки.

Что использовать

Я бы сказал, что в большинстве приложений оригинальный firstOrCreate вполне подходит, а createOrFirst стоит использовать только в параллельной среде с большим количеством трафика.

Дополнительные материалы

Предыдущая Статья

Laravel: Паттерн Pending Object

Следующая Статья

Написание CSS в 2023 году: Отличается ли он от того, что было раньше?