Каковы Транзакционные Границы для Командных Обработчиков и Выполнения? - PullRequest
1 голос
/ 15 июля 2010

Давайте рассмотрим пример пользовательского интерфейса для редактирования информации о клиенте.Пользователь редактирует 5 полей и нажимает «отправить».Поскольку мы хорошие абстракционисты, мы перенесли изменения в 5 полей и сделали их разными командами (описывающими редактирование определенного поля).

Обработчики команд заканчивают тем, что задают свойства для сохраняемых объектовс помощью такого инструмента, как NHibernate, в итоге мы выполняем ОБНОВЛЕНИЕ для базы данных.

Мой главный вопрос: с точки зрения производительности базы данных, имеет ли смысл выпускать единственное ОБНОВЛЕНИЕ?оператор или это нормально, чтобы выдать 5 различных операторов UPDATE?

Мне нравится идея, что обработчик команд является границей транзакций.Либо он работает, и транзакция фиксируется, либо нет, и транзакция откатывается (и мы, возможно, добавим очередь в очередь, чтобы повторить попытку).Успех или неудача каждой команды не зависит от другой.

Другой подход может заключаться в том, чтобы обернуть обработку этих команд в одну транзакцию базы данных, чтобы, когда NHibernate решает сбросить, он заканчивал тем, что отправлял однуОБНОВИТЬ.Но это делает обработку команд соглашением типа «все или ничего», и я не могу обязательно выполнять их асинхронно.

Но если бы я хотел убедиться, что все команды выполнены правильно, и выполнить откат полностьюв случае неудачи?Может быть, есть одна распределенная транзакция, содержащая много меньших транзакций?Это может привести к конфликту базы данных, увеличивая риск взаимоблокировок, что замедляет обработку (еще больше увеличивая риск взаимоблокировок).Но в то же время последовательность является ключевым фактором.Я полагаю, что это компромисс между доступностью и согласованностью (см. CAP).

1 Ответ

4 голосов
/ 16 июля 2010

С точки зрения базы данных почти всегда лучше выпустить одно обновление - но это зависит от контекста, действительно ли это важно или нет.

Однако я не уверен, что как «хороший абстракционист»'вы действительно хотите ввести 5 команд, когда 5 полей редактируются.То, что вы действительно хотите сделать в DDD, - это ввести одну команду для каждой логической операции, которую пользователь выполняет через пользовательский интерфейс.Обычно это только один на операцию, хотя для более сложных сценариев может быть больше одного.В качестве простого примера: если кто-то обновляет свой адрес, у вас нет одной команды для каждого поля - у вас есть команда для обновления адреса.

Наименьший уровень детализации, который у вас есть, будет командойпоэтому все, что находится в обработчике команд, должно быть включено в транзакцию.Что мы делаем, так это помещаем команды в единицу работы, поэтому, когда мы выдаем более одной команды, они либо все проходят, либо все терпят неудачу.В конце мы фиксируем транзакцию, что означает, что любые измененные объекты (для нас это совокупный корень плюс события, так как мы используем источник событий) сохраняются.Если вы используете NHibernate для этого, он потенциально может сделать это за одну операцию - хотя, конечно, это зависит от того, что вы делаете с постоянством.

...