Как использовать Rich Domain с Massive Operations?

Поскольку я работаю над относительно сложной проблемой, я бы хотел использовать подход, управляемый доменом, для ее решения. Проблемой является расчет ежемесячных счетов для клиентов. Текущее решение реализовано как очень длинная хранимая процедура, которую трудно поддерживать.

Я хотел бы использовать объектно-ориентированную среду (возможно, POCO и Entity Framework), но я беспокоюсь о производительности. Текущий SP занимает около 10 минут, чтобы сгенерировать более 300 000 записей с помощью операций набора. Я думаю, что это будет очень трудно достичь с любым ORM, так как он будет загружать сущность один за другим и отправлять обновления таким же образом. (Предыдущая версия занимала 5 часов при доступе к записям по очереди.)

Как бы вы создали богатую модель для массовых операций?

2 ответа

Решение

Я стараюсь не использовать массовые операции, насколько это возможно, когда применяю модель с расширенным набором доменов

Некоторые партии могут быть заменены событиями. Например, мне нужен ежедневный отчет о количестве заказов.

Пакетное решение:

Задача планирования, которая запускается в конце дня, собирает данные из заказов, размещенных сегодня.

Или использовать события

PlaceOrderService публикует OrderPlacedEvent при размещении нового заказа. И eventHandler получает событие и вставляет в T_ORDER_COUNT_ENTRY

|TODAY     |ORDER_ID|
|2012-04-01|123     |
|2012-04-01|124     |

Мы могли бы использовать SQL count() для вычисления ежедневного отчета о количестве заказов.

Некоторые другие партии могут работать параллельно. Например, мои заказы должны быть отменены автоматически, если они не оплачены в течение 30 минут.

Исходное пакетное решение извлекает все заказы, выполненные один за другим, и вызывает их отмену ().

Текущее решение извлекает все заказы, удовлетворенные один за другим, и отправляет сообщение OrderIsOverdue. Обработчики сообщений получают сообщение, содержащее идентификатор заказа, получают заказ и затем отменяют его.

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

Подумав, я понял, что ваш вопрос похож на этот:

Как переписать хранимую процедуру в код, управляемый доменом?

Теоретически это возможно. Все, что вам нужно сделать, это идентифицировать и разделить проблемы, существующие в вашей хранимой процедуре, и переписать их объектно-ориентированным способом.

Сказав это, я предвижу следующие задачи для решения этой задачи:

1 - Предварительная загрузка данных

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

Для этого обратитесь к [совокупные корни]

Этот подход имеет большой недостаток: высокое потребление памяти. Отсюда следующий шаг ниже.

2 - итерация данных без предварительной загрузки

Хранимая процедура имеет такую ​​вещь, как курсор. Это не загружает данные, а выполняет их итерацию эффективным способом. В доменном коде вы не можете достичь такого же эффекта. Есть что-то близкое к курсорам - [SqlDatReader], но в действительности оно не использует курсоры SQL за кулисами, поэтому будьте осторожны с этим.

3 - массовые модификации данных

Эту часть легко реализовать, правильно внедрив [Unit of Work] в модель предметной области. Таким образом, все модификации фиксируются в базе данных одновременно, даже если вы вызываете операции модификации для экземпляров сущности один за другим.

Я не уверен, добавил ли это какой-то свет в вопрос, но дайте мне знать, если у вас есть какие-либо комментарии, на которые я мог бы ответить.

Другие вопросы по тегам