У меня есть последовательность клиентов, которая должна обрабатываться параллельно.Покупатели покупают товары в магазинах, и я должен убедиться, что:
- Запас не отрицательный
- Покупатель покупает в самом дешевом магазине.
Я хочуэто должно быть в высокой степени одновременным, и поэтому я хотел бы сделать свое решение коммутативным и использовать commute
вместо alter
и повторить, что приведет к повторной записи.Я хотел бы только повторить обработку клиента, когда у меня заканчивается товар.По этой причине я предпочитаю делать каждый товар на складе ref
.Затем я бы использовал validator
, чтобы убедиться, что каждый товар не опустился ниже нуля.Например:
Товар на складе:
(def stock-item (ref 10))
Валидатор:
(defn valid-stock-balance? [stock-bal]
(>= stock-bal 0))
Установка валидатора для ссылки:
(set-validator! stock-item valid-stock-balance?)
Тогдавнутри транзакции я попытался бы commute
акции, как показано ниже:
(defn- buy-product [amount customer]
(try
(commute stock-item - amount)
(catch Exception e (process-customer customer))))
Процесс клиента будет выглядеть примерно так:
шаг 3 использует: buy-product
(defn- process-customer [customer]
(dosync
"Process `customer`. Consists of three steps:
1. Finding all stores in which the requested products are still available.
2. Sorting the found stores to find the cheapest (for the sum of all products).
3. Buying the products by updating the `stock`
))
Вопросы
- Используется ли
try catch
в buy-product
побочный эффект, который не должен использоваться в транзакции в process-customer
? - Каковы повторения вызова
process-customer
внутри buy-product
?Это просто приводит к вложенной транзакции или взрывается?