Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
А в базу можно писать асинхронно, вызываю команду на сервере, и не дожидаясь завершения.
А в случае с CQRS мы сначала пишем в ненадежное хранилище (ибо писать в надежное — дорого), а потом переливаем данные в надежное.
А если во время записи произошла ошибка? Поскольку у вас fire-and-forget, вы об этом не узнали. Данные в БД не обновились. Что делать?
Ну нет. В случае с CQRS запись делается в настолько надежное хранилище, насколько нужно (т.е., если нужна персистентность — то в честно персистентное).
Вероятность на СУБД получить отказ в одной операции update, когда работает все остальное, настолько мала, что ей можно пренебречь.
А в чем тогда выигрыш быстродействия, если нам все равно писать надо на каждый запрос? Все равно все запросы на запись выстраиваются в очередь и клиент ждет завершения.
В том, что запись в хранилище, оптимизированное для записи, — быстрее, чем запись в хрналищие, оптимизированное для чтения. А между ними данные можно трансферить тем способом, который оптимален для задачи.
В SQL Server этого можно добиться только одним способом, который по сути является ошибкой проектирования.
Сокращать надо время ожидания пользователя, а не время записи. Поэтому чем больше лаг между отправкой команды и записью в хранилище для чтения, тем хуже.
Так этот конкретный пользователь, который открывает статью на чтение, не ждет результата записи счетчика прочитанных.
Прямое применения CQRS еще большая ошибка, чем неправильно построенный индекс в SQL Server.
Он как минимум ждет ответа хранилища.
Что вы понимаете под «прямым применением»?
Хранилища на запись, которое должно быть быстрее, чем хранилище на чтение.
Как бы вы не извращались, но все равно вы под нагрузкой будете использовать кеш для чтения. И это сделает CQRS бесполезным в 99% случаев.
Классы, определяющие контракт API MoneyFlow для экранов списка, создания и редактирования операций.
public class ChargeOpForAdding public class ChargeOpForList : ChargeOpForAdding public class ChargeOpForEditing : ChargeOpForList
//Проверяем входные данные
CheckingData(op);
...
_chargeOpsStorage.CreateChargeOp(op);
//обновить отчет за месяц
public void UpdateMonthReport(Guid userId, ECategory category, int year, int month, double sum)

Как устроен наш код. Серверная архитектура одного проекта