Информация об изменениях

Сообщение Re[11]: Блокировки в бизнес-слое от 28.09.2017 7:53

Изменено 28.09.2017 7:59 ·

Re[11]: Блокировки в бизнес-слое
Здравствуйте, Poul_Ko, Вы писали:

P_K>Здравствуйте, ·, Вы писали:


P_K>·>Или я тебя совсем не понимаю, или ты не ту цель пытаешься достигнуть. Цель не добиться "одновременности" (что это вообще значит?!), а создать согласованное состояние, установить причинность событий.

P_K>Не пытаюсь добиться одновременности, а наоборот, пытаюсь от неё избавиться, так как она порождает проблемы.
P_K>Способов избавления пока вижу два — либо всегда всё жёстко делать последовательно, либо на каких-то блокировках не давать делать одновременно некоторые операции.

P_K>>>·> Любые последующие изменения цены "официально" считаются, что произошли после, а значит не должны влиять на заказ.

P_K>>>Категорически нет. Смотрите выше — изменение цены после приводит к пересчёту неподтверждённых заказов!
P_K>·>1. Создать неподтверждённый заказ товара по ценам из справочника.
P_K>·>2. Показать заказ клиенту, клиент шлёт команду "подтвердить".
P_K>·>3. Сверяем цены в заказе с ценами в справочнике
P_K>·>4.1 Цены равны — ставим статус "подтверждён"
P_K>·>4.2 Цены не равны — возвратить клиенту ошибку, пересчитать заказ с учётом новых цен и goto 2.
P_K>·>Т.е. по сути у тебя тут распределённая система из двух компонент — клиент и сервер — они и должны согласовываться.
P_K>Нет, это не соответствует действительности.
P_K>У клиента одно действие — создать новый неподтверждённый заказ. Этот заказ создаётся и болтается в системе пока его не подтвердят или не отменят. И пока он болтается неподтверждённый цена в нём всегда должна строго соответствовать цене из справочника.
Это означает, что тебе нужно задать явную временнУю зависимость заказа от цены. Помимо того, что я упомянул уже, вариант — заблокировать продукт перед созданием ордера:
SELECT Price FROM Products WHERE Id = 1 FOR UPDATE;
...
INSERT INTO Orders()

Но тут надо очень осторожно, ибо плохо продуманные блокировки — путь к deadlock.
Re[11]: Блокировки в бизнес-слое
Здравствуйте, Poul_Ko, Вы писали:

P_K>Здравствуйте, ·, Вы писали:


P_K>·>Или я тебя совсем не понимаю, или ты не ту цель пытаешься достигнуть. Цель не добиться "одновременности" (что это вообще значит?!), а создать согласованное состояние, установить причинность событий.

P_K>Не пытаюсь добиться одновременности, а наоборот, пытаюсь от неё избавиться, так как она порождает проблемы.
P_K>Способов избавления пока вижу два — либо всегда всё жёстко делать последовательно, либо на каких-то блокировках не давать делать одновременно некоторые операции.

P_K>>>·> Любые последующие изменения цены "официально" считаются, что произошли после, а значит не должны влиять на заказ.

P_K>>>Категорически нет. Смотрите выше — изменение цены после приводит к пересчёту неподтверждённых заказов!
P_K>·>1. Создать неподтверждённый заказ товара по ценам из справочника.
P_K>·>2. Показать заказ клиенту, клиент шлёт команду "подтвердить".
P_K>·>3. Сверяем цены в заказе с ценами в справочнике
P_K>·>4.1 Цены равны — ставим статус "подтверждён"
P_K>·>4.2 Цены не равны — возвратить клиенту ошибку, пересчитать заказ с учётом новых цен и goto 2.
P_K>·>Т.е. по сути у тебя тут распределённая система из двух компонент — клиент и сервер — они и должны согласовываться.
P_K>Нет, это не соответствует действительности.
P_K>У клиента одно действие — создать новый неподтверждённый заказ. Этот заказ создаётся и болтается в системе пока его не подтвердят или не отменят. И пока он болтается неподтверждённый цена в нём всегда должна строго соответствовать цене из справочника.
Это означает, что тебе нужно задать явную временнУю зависимость заказа от цены. Помимо того, что я упомянул уже, вариант — заблокировать продукт перед созданием ордера:
SELECT Price FROM Products WHERE Id = 1 FOR UPDATE;
...Cost = Price * Qty...
INSERT INTO Orders(...) VALUES(..., Cost, ...);

Но тут надо очень осторожно, ибо плохо продуманные блокировки — путь к deadlock.