212 похожих чатов

Задача Есть автомобили и водители. Бизнес правила: 1. На одну машину не больше

2 водителей
2. На одного водителя не больше не 3 машин
3. Нельзя удалить машину, если у неё есть как минимум 1 водитель

Юзкейсы
1. Добавить машину
2. Удалить машину (соблюдая правило 3)
3. Добавить водителя
4. Удалить водителя
5. Зарегистрировать машину за водителем (соблюдая правила 1 и 2)

Есть ли возможность это всё смоделировать так, что у нас везде будет transaction consistency (соблюдая правило, один агрегат на транзакцию), и при этом не будет одного жирного агрегата?

16 ответов

24 просмотра

2 агрегата. 1. машина айди + водители айдис 2. водитель айди + машины айдис Их хватит чтобы покрыть все 3 инварианта

Dmitry-Croft Автор вопроса
Sergei Baikin
2 агрегата. 1. машина айди + водители айдис 2. во...

А в каком из каждых агрегатов должно проверяться каждое из инвариантов?

Dmitry Croft
А в каком из каждых агрегатов должно проверяться к...

Бизнес правила: 1. На одну машину не больше 2 водителей ---- в первом 2. На одного водителя не больше не 3 машин --- во втором 3. Нельзя удалить машину, если у неё есть как минимум 1 водитель --- в первом

Dmitry-Croft Автор вопроса
Sergei Baikin
Бизнес правила: 1. На одну машину не больше 2 води...

Тогда, чтобы реализовать этот юзкейс: 5. Зарегистрировать машину за водителем (соблюдая правила 1 и 2) Мне нужно в рамках одной транзакции работать с двумя агрегатами? т.е. менять стейт двух агрегатов в одной транзакции

Dmitry Croft
Тогда, чтобы реализовать этот юзкейс: 5. Зарегист...

Я бы сделал eventuell consistency. Регистрировал паралельно и там и там и в случае неуспеха подчищал. Вряд ли там будет высококонкурентный процесс. Так что такое не должно случатся практически никогда.

То что вам насоветуют с consistency, зависит конкретно от лоада

Dmitry-Croft Автор вопроса

Меня интересует возможность реализации этого кейса конкретно при помощи transaction consistency и чтобы в рамках одной транзакции не менялся стейт нескольких агрегатов (при этом не создавая ожин жирный агрегат на все случаи)

тут важно еще какая вероятность что возникнет гонка. Если она незначительна - то есть лочить мы будем только отдельные агрегаты - то достаточно просто взять из базы два агрегата через select for update, и обновить их в одной транзакции. Таким образом избегаем необходимости в эвеншуал консистенс

в целом, если убрать ограничение транзакционной консистентности, что мы можем придумать... - добавить машину - тут нет возможности сломать инварианты. То же про "добавить вобителя". Их игнорим. - удалить водителя - тут по сути тоже, удаляется водитель и как следствие снимается регистрация (хотя я бы это уточнил). Тут нет особо возможности операции упасть из-за бизнес штук. я бы это просто вынес в очереди и retry on failure сделают свое черное дело - зарегистрировать машину за водителем - тут можно пойти на хитрость. Для начала мы закрепляем чет типа заявки за водителем. В рамках этого агрегата мы будем форсить правило номер 2. Если зафэйлилась операция - значит зафэйлилась. Дальше второй агрегат связывает водителя и авто, так форсим первое правило. Если оно зафэйлилось - то значит надо снять заявку. Это можно все делать eventually через ивенты - в худшем случае какое-то небольшое время человека нельзя будет зарегать за машиной, но стэйт разрулится. - ну и удаление авто - тут опять же мы храним список водителей за которыми зарегистрирована машина и в целом уже все хорошо. то есть по факту только операция регистрации водителя требует более одного агрегата на транзакцию и eventual consistency. за счет того что мы сначала резервируем слот а потом регистрируем система не может войти в невалидное состояние, нам легко потом будет откатиться.

Dmitry-Croft Автор вопроса

> один агрегат на транзакцию для этой операции не выйдет просто в силу характера many-to-many ассоциаций А есть статьи или, может, где-то в книжке написано, по этой проблеме?

Мне кажется идеи с закреплением заявки за водителем можно добиться и через transaction consistency. Единственный момент - если агрегаты хранятся в разных местах, то так сделать не получится На скрине пример. В юзкейсе просто нужно вызвать car.addDriver(driver)

Dmitry Croft
> один агрегат на транзакцию для этой операции не ...

Агрегаты по своей сути документы, и атомарность изменения стэйта можно гарантировать только в пределах одного документа за раз. Моделировать many-to-many через документы не выйдет. В этом как бы секрет успеха реляционных баз данных

Alexander
screenshot Мне кажется идеи с закреплением заявки за водителе...

Да, можно, но у автора было требование "одна транзакция один агрегат". Это увы нельзя с many to many. Тут будет одна транзакция два агрегата.

Dmitry-Croft Автор вопроса
Sergey P
Да, можно, но у автора было требование "одна транз...

А нельзя сделать новый агрегат, где будет массив carIds по водителю. И driverIds по машине?

Похожие вопросы

Обсуждают сегодня

Господа, а что сейчас вообще с рынком труда на делфи происходит? Какова ситуация?
Rꙮman Yankꙮvsky
29
А вообще, что может смущать в самой Julia - бы сказал, что нет единого стандартного подхода по многим моментам, поэтому многое выглядит как "хаки" и произвол. Короче говоря, с...
Viktor G.
2
30500 за редактор? )
Владимир
47
а через ESC-код ?
Alexey Kulakov
29
Чёт не понял, я ж правильной функцией воспользовался чтобы вывести отладочную информацию? но что-то она не ловится
notme
18
У меня есть функция где происходит это: write_bit(buffer, 1); write_bit(buffer, 0); write_bit(buffer, 1); write_bit(buffer, 1); write_bit(buffer, 1); w...
~
14
Добрый день! Скажите пожалуйста, а какие программы вы бы рекомендовали написать для того, чтобы научиться управлять памятью? Можно написать динамический массив, можно связный ...
Филипп
7
Недавно Google Project Zero нашёл багу в SQLite с помощью LLM, о чём достаточно было шумно в определённых интернетах, которые сопровождались рассказами, что скоро всех "ибешни...
Alex Sherbakov
5
Ребят в СИ можно реализовать ООП?
Николай
33
https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_h_common.erl#L174 https://github.com/erlang/otp/blob/OTP-27.1/lib/kernel/src/logger_olp.erl#L76 15 лет назад...
Maksim Lapshin
20
Карта сайта