2017-02-08 6 views
3

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

Я знаю, что мы не должны обновлять несколько экземпляров совокупности в одной транзакции. Тем не менее, я думаю, что «множественные совокупные экземпляры» здесь означают множественный экземпляр разных типов агрегатов. Я прав?

Say, Продукт и BacklogItem два различных агрегатов, поэтому мы должны избегать обновления продукта и для BacklogItem в одной транзакции.

Но что делать, если мне нужно обновить несколько экземпляров того же типа агрегата? Скажем, мне нужно обновить все продукты 'name. Каков наилучший способ справиться с этим?

псевдокод

//Application Service 
public void ChangeTitle(string newName) 
{ 
    using(uow.BeginTransaction()) 
    { 
     IEnumerable<Product> products = repo.GetAll(); 
     foreach(var product in products) 
     { 
      product.ChangeName(newName); 
     } 
    } 
} 
+0

Нет, вы не можете. Если вам нужно это сделать, то границы вашего Агрегата ошибочны. –

+0

@ConstantinGALBENU Не обязательно. Бывают случаи, когда может быть приемлемым нарушение правила и масштабируемость торговли для обеспечения сильной согласованности. – plalx

ответ

3

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

Почему все переименования не удаются или не удаются, если нет никаких инвариантов для защиты от всех этих AR. Например, если пользовательский интерфейс позволяет пользователям одновременно переименовывать несколько продуктов, а некоторые пользователи переименовывают сотни из них. Если один продукт не был переименован из-за конфликта параллелизма, например, было бы лучше не переименовывать какие-либо продукты или не информировать пользователя о том, что один из них не удалось?

Вы всегда можете нарушать правило, но вы должны понимать, что чем больше AR, вовлеченных в транзакцию, тем больше вероятность того, что вы столкнетесь с транзакционными сбоями из-за конфликтов параллелизма (при условии, что могут возникнуть разногласия).

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

0

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

  • ошибки вызывают или исключения из-за нарушения параллелизм, если вы используете Оптимистичный руководству параллелизма
  • задержки вызывает из-за блокировками, если вы используете пессимистично руководство параллелизма
  • проблему согласованности данных
  • причины, если вы не используете никакого управления параллелизмом

Это руководство относится ли размер т hings, который меняется, становится шире (изменяя больше типов агрегатов) или глубже (изменяя больше экземпляров одного и того же агрегата). Вместо того, чтобы точно учитывать, что меняется, подумайте, каков риск того, что некоторые части этого изменения будут противоречить аналогичному изменению, сделанным другим человеком одновременно?

Разработка DDD для высококонкурентных многопользовательских систем - это то, откуда берутся рекомендации по созданию небольших независимых агрегатов. Если это не ваше дело, вы можете потенциально нарушить руководство, основанное на вашем собственном анализе рисков.

0

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

Есть ли причина, по которой это должно быть сделано за одну транзакцию? если это так, то кажется, что в вашей модели отсутствует концепция. Эта концепция может быть не чем иным, как простым диспетчером процессов, который обновляет несколько агрегатов в вашем домене и отчитывается, когда все завершается успешно, и даже может включать в себя некоторые механизмы повтора или другую обработку исключений в случае сбоя в одном из обновлений. Этот диспетчер процессов можно назвать «массовым renamer» или что-то в этом роде?

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