Sorry if it's duplicated, I have searched a lot in SO, but I didn't find a matched question.
I know we shouldn't update multiple aggregate instances in one transaction. However, I think the "multiple aggregate instances" here means multiple instance of different aggregate types. Am I right?
Say, Product and BacklogItem are two different aggregates, so we should avoid updating both Product and BacklogItem in one single transaction.
But what if I need to update multiple instances of the same aggregate type? Say, I need to update all products' name. What's the best way to deal with it?
pseudocode
//Application Service
public void ChangeTitle(string newName)
{
using(uow.BeginTransaction())
{
IEnumerable<Product> products = repo.GetAll();
foreach(var product in products)
{
product.ChangeName(newName);
}
}
}
The type of AR is irrelevant, ARs are always transactional boundaries. When working with many of them you should usually embrace partial failures and eventual consistency.
Why should all renames fail or succeed if there are no invariants to protect across all these ARs. For instance, if the UI did allow users to rename multiple products at a time and some user renames hundreds of them. If one product failed to be renamed because of a concurrency conflict for instance, would it be better not to rename any of the products or inform the user that one of them failed?
You can always violate the rule, but you must understand that the more ARs that are involved in a transaction, the more likely you are to experience transactional failures due to concurrency conflicts (assuming contention can occur).
I usually only modify multiple ARs in one transaction when there are invariants crossing ARs boundaries and I can't afford to avoid dealing with eventual consistency.