Re: Massive stored proc data base operation to DDD

"[email protected] [domaindrivendesign]" <[email protected]> 23 Nov 2014 18:05:36 -0800
Newsgroups gmane.comp.programming.domain-driven-design
Message-ID <[email protected]>
Thanks for responding. I will try to answer your questions.
 

 1. It is a B2B scenario. So, an agent through the application classify a million products. There is another agent does the same for a different set of products. You can consider the scenario of Amazon agents dealing with marketplace products.
 

 2. Your assumption is correct. The issue is the aggregate loading and persisting the state changes for millions of products. 
 

 3. The event MarkAllProductsAsVegetablesOrNot (I slightly modified what you have suggested) is appropriate. When that event is run, the aggregate has to read the product entity from the DB via repository, changes it's state based on any business rule and then persist. I may have to use a batch operation of all the entities which may save time.
 

 So the solution seems to be it is okay to do the business validation in the domain and not in the stored proc, and do the persistence as a batch operation. The repository will have a method like ProductRepositor.PersistAllProductsAsVegetablesOrNotAsBatch. I may use the batch operation in a stored procedure which takes only products and it's classification and completely avoid the business logic in it.
 

 Let me know what you think about my conclusion.

---In [email protected], <rikard@...> wrote :


 On 22 Nov 2014 06:31:58 -0800
 "varghese.pallathu@... mailto:varghese.pallathu@... [domaindrivendesign]"
 <[email protected] mailto:[email protected]> wrote:
 
 > Lets take an example of a product classification. All the products
 > needs to be classified as vegetable or not. This is a command which
 > should take some time to complete because there are millions of
 > products. This is a B2B scenario, so the agents do this operation
 > quite often like few times every day. This is a UPDATE operation not
 > a read operation. The business logic is, the product can be
 > classified as vegetable if that product is from company A, B & C. If
 > the product is not from those companies they are not vegetables.
 > There are millions of products in the database with it's vendor.
 > Approaching this from a data perspective, this can be done in a
 > stored procedure with few lines of code. The operation may take only
 > few seconds even if it is done synchronize. 
 
 I find it strange that you need to update objects so often with an
 attribute which should be immutable (but let's consider that this is
 toy example and as with most toy examples, let's not get to much into
 it).
 
 > Now let me approach this from a DDD perspective. As I understand,
 > the DDD goes against the idea of putting the logic in the stored
 > procedure. The logic can be put as a behavior on product which can
 > self classify based on who is the source, or the aggregate root can
 > do that job. To do this, all the million products need to be read
 > into memory from the database, process and then save it back to the
 > database through the repository (whether it is SQL, Document based,
 > mySql or whatever). The problem here is the large amount of memory
 > this operation needs when done using the DDD approach. If the
 > operation is done in chucks like 50,000 the repository has to first
 > figure out how may products needs to be classified and the domain has
 > to plan the long running operation in chunks. Surely, this approach
 > is going to take more time and a bad user experience for the user who
 > has to wait more time than a process than a stored procedure takes. 
 
 While DDD is often explained as OO on stereoids, don't think about DDD
 as classes in OO language. I've seen ERPs which have domain layer
 implemented directly in the database (not saying that's a good thing)
 and DDD can certainly be practiced with non OO languages.
 
 But for the sake of argument, let's consider it from OO perspective...
 So you think the issue of aggregate boundary requires retrieving and
 persisting aggregates as a whole?
 That's true only if you have anemic aggregates - and thus need to check
 if they are still valid. This is usually avoided by removing public
 access from aggregate properties and exposing methods such as
 markAsVegetable()
 
 Implementation behind such method can be a simple UPDATE which will
 mark that aggregate as vegetable.
 So the question now becomes, what about updating multiple aggregates at
 once?
 In my mind this is perfectly fine if you are working with a single
 relational DB.
 In DDD approach you could have Domain event MarkAllVegetables which
 would change all required attributes in DB table.
 
 > What is the reasonable approach to DDD when it comes to long running
 > massive data processes? Is the delay expected, so the app has to
 > inform the user that the classification is going to take time like 5
 > minutes or so and will let the user know when that is complete? And
 > should not use stored procedure to have the classification logic, but
 > have the business logic as part of the domain. 
 
 DDD doesn't force you to implement slow or inadequate solutions. That's
 usually the result of using specific frameworks or working in OO way
 when it's not appropriate.
 
 > You can think about the classification business logic which can
 > change in the future. In this example, it is based on the vendor who
 > provides the product. That can change to country. For example, all
 > the products come from Country A will be wine. There is a greater
 > flexibility with having this logic as part of the domain. But what
 > worries me is the large amount of memory this operation has to take. 
 
 If you find yourself trying to force some logic into specific
 aggregate, but it feels wrong for some reason, try to evolve the
 domain. You are probably missing a thing or two in it.
 
 Regards,
 Rikard
 
 -- 
 Rikard Pavelic
 https://dsl-platform.com/ https://dsl-platform.com/
 http://templater.info/ http://templater.info/