besogonskiy
@besogonskiy

Как успеть получить max id и добавить элемент с id+1 пока не заняли?

Использую две схожие модели и у них не должно быть одинакового значения в поле id. То есть, должна соблюдаться уникальность внутри двух моделей. Решил эту задачу при помощи функции:

static function getNextId() {
        $mpMaxId = MasterProduct::max('id');
        $gpMaxId = GroupedProduct::max('id');
        if ( $mpMaxId > $gpMaxId ) {
            return $mpMaxId+1;
        } else {
            return $gpMaxId+1;
        }
    }

И в большинстве случаев это работает. Функция всегда возвращает максимальный из двух таблиц ID+1 и перед тем как записать новую модель этот идентификатор заполняется. НО вот случается такое, что при попытке сохранить происходит ругание на неуникальность ключа. В чем может быть дело?

Может как-то в транзакции бронировать этот id? Или может несколько пользователей одновременно создавали элементы (товары) и пока мы получали id для одного, другой уже захватил этот id?

Как нам быть? в redis закидывать этот id и оттуда доставать?
  • Вопрос задан
  • 95 просмотров
Пригласить эксперта
Ответы на вопрос 1
@oxidmod
Можно в редисе завести счетчик и инкрементить его. Инкремент атомарный, если один процесс получит какое-то значение, другой никогда такого-же не получит
Вопрос конечно как обеспечить его живучесть... Если редис упадет\потеряет данные, то все пойдет наперекосяк

Второй вариант, завести вспомогательную таблицу с одной автоинкрементной колонкой
Когда нужен новый айдишник, просто инсертить в эту таблу запись и брать last_inserted_id

Третий вариант, если у вас постгрес, то можно использовать одну последовательность для генерации айдишек в обеих таблицах... Будет самый простой и прозрачный вариант

Но лучше всего сесть и нормально подумать чем вызвано такое требование и поискать решение корневой проблемы, а не городить костыли
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
DKLINE Санкт-Петербург
от 120 000 до 150 000 ₽
SaveTime Москва
от 170 000 до 250 000 ₽