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

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

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

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

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

16 ответов

8 просмотров

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 по машине?

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

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

читать файл максимально быстро? странный вопрос))
zamtmn
53
тоесть, указав return eax, сгенерируется никому ненужная инструкция mov eax,eax ?
Aiwan \ (•◡•) / _bot
24
Кто-нибудь решал проблему с автоматическим скроллингом к выбранной ячейке в TDBGrid в Lazarus? Проблема в том, что есть допустим 3 столбца, третий столбец виден наполовину, вк...
Дмитрий Логинов
1
Приветствуем всех! Устали без проектов? Если вы программист и хотите получать стабильные заказы, компания Elif предлагает вам недельный курс по поиску проектов и их ведению. ...
Elif
1
А чего сейчас в моде вместо Error для эксепшенов? А то я тут внезапно узрел что он не рекомендуется :) У Try::Tiny какой-то совершенно ужасный синтаксис если надо конкретные э...
Denis F
19
а зачем этот вопрос для удаления из чата?
Mёdkinson Medvezhkin
63
Чорт! Чорт! Чорт! Стала ставить через GetIt (написано же, что ручками не рекомендуется) Сломалось на дублировании моей TSkLabel. Чтож мне ее по всем проектам переименовывать в...
Катерина Свиридова
7
Привет. Сразу скажу, что на C/C++/Rust я не пишу, но тем не менее возникла потребность дебага C/C++/Rust кода. Суть: есть серверное приложение, которое периодически ведёт себ...
ninekeem 🐳
4
Hey someone plz help to resolve my issue here is my table... Log { id user_id type target_ct target_obj_id action_ct action_obj_id workspace_id created_at } i wanna fil...
Rahul Singh
1
всем привет! углубившись в плюсы и начав изучать реверсинг понял, что без асм'а никуда со своими высокоабстрактными представлениями начал изучать механизмы асма, и не совсем п...
9
Карта сайта