Задача
Остатки дистрибьютора меняются весь день: приходят заказы, уезжает машина, возвращается товар, кто-то правит пересчёт. Если каждое из этих действий пишет в остаток само по себе, рано или поздно два из них столкнутся, и цифра на экране разойдётся с полкой.
Один писатель
В Scoperly каждое изменение остатка идёт через один сервис: приход, принятый заказ, отмена, перемещение между складами, продажа на месте. Итог по товару — не отдельное число, которое может уплыть. Он равен сумме по складам, и за этим следит сервис.
Резерв — ещё не списание
Оформленный заказ пока не снимает товар с полки. Он его резервирует, чтобы никто другой не пообещал ту же коробку:
- Заказ оформлен: резерв растёт.
- Заказ принят: остаток и резерв уменьшаются вместе.
- Заказ отклонён или отменён до принятия: резерв уменьшается обратно.
- Заказ отменён после принятия: товар возвращается в остаток.
Блокировки там, где это важно
При оформлении заказа строки его товаров заблокированы до конца транзакции. Двое, покупающие последнюю коробку, не получат её оба: второй увидит понятное «недостаточно товара», а не обещание, которое склад не выполнит.
Проверка сумм
Эти правила записаны и как проверки: итог равен сумме по складам, резерв совпадает с открытыми заказами. Мы прогоняем их на данных перед большими выпусками, потому что правило, которое никто не проверяет, постепенно перестаёт быть правдой.