kimono
@kimono
Web developer

Как в Yii2 обработать одновременные запросы на вставку одинаковых значений в БД?

Есть модуль аукциона для объявлений Items. Есть модель "Ставка" (id, user_id, item_id, price).
В таблице ставок нет уникального индекса на item_id+price.

Есть ли возможность в Yii2 предотвратить вставку одинаковых значений предложенных цен разными пользователями для определенной модели объявления item_id?
С виду кажется, что нужно просто прописать уникальный валидатор в модель ставки для валидации пары значений item_id + price, но на деле при одновременной посылке одинаковых запросов, обе проходят валидацию, а при сохранении в базу ошибок не выводится.
Варианты?
  • Вопрос задан
  • 736 просмотров
Решения вопроса 2
webinar
@webinar Куратор тега Yii
Учим yii: https://youtu.be/-WRMlGHLgRg
Не писать сразу в базу, а создать очередь, в виде промежуточной таблицы или кеша или файла. И вот из нее брать по одной записи и заносить в боевую (например кроном раз в минуту), тогда не будет одновременности.
Как вариант еще транзакции:
www.yiiframework.com/doc-2.0/yii-db-transaction.html
www.yiiframework.com/doc-2.0/guide-db-active-recor...
Ответ написан
Wolfnsex
@Wolfnsex
Если не хочешь быть первым - не вставай в очередь!
В таблице ставок нет уникального индекса на item_id+price.
Почему?

С виду кажется, что нужно просто прописать уникальный валидатор в модель ставки для валидации пары значений item_id + price
Лично мне - так не кажется.

Есть ли возможность в Yii2 предотвратить вставку одинаковых значений
Эта возможность должна быть в БД, а не в Yii2, чисто логически.

при одновременной посылке одинаковых запросов, обе проходят валидацию
А как Вы одновременно генерируете одинаковые запросы? (просто интересно)

Варианты?
1. Добавить UNIQ-индекс и не изголяться
2. Блокировки
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
Demetriy
@Demetriy
веб и мобильная разработка
Наверно можно и без очередей:
1) Кладете проверку на существование записи и вставку в одну транзакцию;
2) Вначале транзакции вешаете блокировку на чтение\запись таблицы или строки;
3) Снимаете блокировку когда все сделаете.

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

Материалы:
https://habrahabr.ru/post/46542/
https://stackoverflow.com/questions/6621303/how-do...
Ответ написан
@BorisKorobkov Куратор тега MySQL
Web developer
В таблице ставок нет уникального индекса на item_id+price

А надо.

но на деле при одновременной посылке одинаковых запросов, обе проходят валидацию

https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D...
и https://dev.mysql.com/doc/refman/5.7/en/miscellane...
Ответ написан
Комментировать
Ваш ответ на вопрос

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

Войти через центр авторизации
Похожие вопросы