При отправке заказа , должно произойти несколько вещей:
- складские запасы уменьшаются, если имеется достаточное количество
- продукты, возвращаемые последующими поисковыми запросами, имеют последние запасы ( сумма по артикулам)
- состояние товара на складе должно быть обновлено при изменении, например. от нормального к отсутствию на складе
Простой дизайн должен иметь ProductStock
агрегат root с totalQuantity, состоянием и набором SkuStock
, например:
public Class ProductStock {
private Long id;
private int totalQuantity;
//enum
private InventoryState state;
private Collection<SkuStock> skus;
}
при отправке заказа загрузить все продукты в заказе, найти артикул, уменьшить запас и обновить totalQuantity и состояние, затем опубликовать событие sh (например, обновить поисковый индекс)
Он работает, но производительность плохая, так как
- загружает ВСЕ skus каждого продукта и обновления, вместо только обязательного skus
- ему необходимо ввести блокировку pessimisti c на ProductStock, когда размещение заказов, это означает, что на тот же продукт (другой skus) нельзя сделать другой заказ, что очень плохо для большого трафика
Второй вариант, который я придумал, - это иметь SkuStock
и ProductStock
как совокупные корни, например,
public Class ProductStock {
private Long id;
private int totalQuantity;
//enum
private InventoryState state;
private Map<Long,Integer> skuStocks;
}
public Class SkuStock {
private Long id;
private int quantity;
//enum
private InventoryState state;
}
Итак, рабочий процесс выглядит следующим образом:
Заказ размещен, найдите SkuStock
s в порядок, уменьшение запасов, пессимисти c блокирует ар e применяется только к запрошенному SkuStock
s.
Publi sh SkuInventoryDecrementForOrderEvent
, базовым хранилищем событий является kafka, поэтому его aysn c.
Поймать SkuInventoryDecrementForOrderEvent
, найти связанные ProductStock
s и обновить totalQuantity и состояние, затем запустить ProductInventoryUpdatedEvent
(например. переиндексируйте продукт так, чтобы общий запас и состояние отражались при последующих поисках).
Это хорошо решает проблемы, но вводит избыточность, ProductStock.skuStocks
и SkuStock
, и добавляет сложность системы
Есть ли способ лучше?