Shopify обрабатывает более 14% всех транзакций в сфере электронной коммерции в США. Чтобы последний оставшийся товар не был продан двум покупателям одновременно, каждое оформление заказа защищено системой резервирования. Когда покупатель переходит к оплате, Shopify резервирует выбранные товары на несколько минут. Если платеж проходит успешно, Shopify окончательно списывает их из системы складского учета продавца.
Годами эти два шага выполнялись в разных базах данных. Redis отслеживал, сколько единиц товара покупатели временно зарезервировали, а MySQL вел учет реального количества товаров на складе продавца. Так как ни одна транзакция не могла атомарно обновить обе базы, сбой между двумя записями приводил к рассинхронизации: система либо скрывала товар, который на самом деле был доступен, либо позволяла продать то, чего на складе уже не осталось.
Shopify перенес резервирование из Redis в MySQL, и теперь обе операции выполняются в рамках одной транзакции. Вместо одной строки на товар со счетчиком доступного остатка система использует ограниченный пул строк, где каждая строка представляет одну единицу товара, доступную для бронирования. Благодаря механизму SKIP LOCKED в MySQL 8 параллельные покупатели могут захватывать разные строки, не дожидаясь друг друга, а процесс пополнения не дает пулу разрастаться до масштабов всего складского запаса продавца. Переработанная система успешно выдержала Черную пятницу 2025 года, когда продажи на пике достигли рекордных 5,1 миллиона долларов в минуту.
Этот пример интересен, потому что в нем показан прием "одна строка на место", знакомый по системам бронирования билетов: для каждого места выделяется отдельная строка, благодаря чему покупатели конкурируют за разные строки, и этот подход доказал свою эффективность в реальном продакшене под колоссальной нагрузкой. Кроме того, эта история наглядно показывает, что реляционная база данных с правильно спроектированной схемой таблиц способна выдерживать нагрузки, ради которых многие инженеры по привычке внедряют специализированную инфраструктуру.
Проблема
Представьте распродажу: осталась всего одна толстовка, и два покупателя одновременно нажимают кнопку оплаты. Shopify должен гарантировать, что купить ее сможет только один из них.
В этом и заключается задача механизма защиты от перепродажи (oversell protection). Когда покупатель начинает оплату, система резервирует товары на несколько минут, чтобы никто другой не мог их забрать, пока обрабатывается платеж. Если платеж проходит успешно, Shopify окончательно вычитает эти позиции из складского остатка продавца. Если платеж завершается ошибкой или истекает таймаут, система [... читать дальше]