title: Why modifies only one aggregate instance per transaction?
body: <p>I'm reading Vernon's article <a href="http://dddcommunity.org/wp-content/uploads/files/pdf_articles/Vernon_2011_1.pdf" rel="noreferrer">Effective Aggregate Design</a>. And I have a question about why modifies only one aggregate instance per transaction?</p>
  
  <p>Let's take an example, consider a Warehouse invertory management story.</p>
  
  <p><strong>Inventory</strong> represents an item with quantity in a warehouse. 5 <a href="https://vaughnvernon.co/?page_id=168" rel="noreferrer">Implementing Domain Driven Design</a> books in Shanghai warehouse for instance.</p>
  
  <p><strong>Entry</strong> represents a log about an in/out operation on an <strong>Inventory</strong>. Entering 2 <a href="https://vaughnvernon.co/?page_id=168" rel="noreferrer">Implementing Domain Driven Design</a> books in Shanghai warehouse for instance.</p>
  
  <p>An <strong>Inventory</strong>'s quantity need to be changed if an <strong>Entry</strong> is submitted.</p>
  
  <p>It easily comes to my mind, this is an invarient could be implemented by transactional consistency. </p>
  
  <p><em><strong>Solution A</em></strong>: Using one Aggregate and cluster <strong>Entry</strong> into <strong>Inventory</strong>.</p>
  
  <pre><code>public class Inventory implements Aggregate&lt;Inventory&gt; {
       private InventoryIdentity id;
       private Sku sku;
       private int quantity;
       private List&lt;Entry&gt; entries;
  
       public void add(Entry entry) {
           this.quantity += entry.getQuantity();
           this.entries.add(entry);
       }
  }
  
  public class Entry implements LocalEntity&lt;Entry&gt; {
      private int quantity;
      // some other attributes such as whenSubmitted
  }
  
  public class TransactionalInventoryAdminService impelments InventoryAdminService, ApplicationService {
  
       @Override
       @Transactional
       public void handle(InventoryIdentity inventoryId, int entryQuantity, ...other entry attributes)
           Inventory inventory = inventoryRepository.findBy(inventoryId);
           Entry entry = inventory.newEntry(entryQuantity, ..);   
           inventory.add(entry);
           inventoryRepository.store(inventory);
       }
  }
  </code></pre>
  
  <p><em><strong>Solution B</em></strong>: Using seperate Aggregate for <strong>Inventory</strong> and <strong>Entry</strong>.</p>
  
  <pre><code>public class Inventory implements Aggregate&lt;Inventory&gt; {
       private InventoryIdentity id;
       private Sku sku;
       private int quantity;
  
       public void add(int quantity) {
           this.quantity += quantity;
       }
  }
  
  public class Entry implements LocalEntity&lt;Entry&gt; {
      private Inventory inventory;
      private int quantity;
      private boolean handled = false;
      // some other attributes such as whenSubmitted
  
      public void handle() {
          if (handled) {
              throw .....
          } else {
              this.inverntory.add(quantity);
              this.handled = true;
          }
      }     
  }
  
  public class TransactionalInventoryAdminService impelments InventoryAdminService, ApplicationService {
  
       @Override
       @Transactional
       public void handle(InventoryIdentity inventoryId, int entryQuantity, ...other entry attributes)
           Inventory inventory = inventoryRepository.findBy(inventoryId);
           Entry entry = inventory.newEntry(entryQuantity, ..);   
           entry.handle();
           inventoryRepository.store(inventory);
           entryRepository.store(entry);
       }
  }
  </code></pre>
  
  <p>Both A and B are feasible, but solution B is kind of inelegant for leaving inadvertent oppertunity to invoke <strong>Inventory</strong>.add(quantity) without <strong>Entry</strong> involved. <strong>Is this what the rule (Modifies only one aggregate instance per transaction) tries to point out for me? I'm confused mostly why we should modify only one aggregate in a transaction, what goes wrong if we don't.</strong></p>
  
  <p><em><strong>Update1 start</em></strong></p>
  
  <p>Is it intend to alleviate concurrency problems (with another rule of "make smaller aggregates")? For example, <strong>Entry</strong> is an Aggregate with  relatively low contention and <strong>Inventory</strong> is one with relatively high contetion (assuming that multiple user could manipulate one <strong>Inventory</strong>), it causes unnecessary concurrency failure if I modify them both in a transaction .</p>
  
  <p><em><strong>Update1 end</em></strong></p>
  
  <p>Some further problems need to be addressed if I adopt solution A:</p>
  
  <p>1.What if there are many <strong>Entry</strong> s for an <strong>Inventory</strong> and I need a paged query UI? How to implement a paged query using Collections? One way is to load all <strong>Entry</strong> s and picks what the page need, the other way is InventoryRepository.findEntriesBy(invoiceId, paging), but this seems to break the rule of get an local entity only by get it's aggreate then navigate the object graph.</p>
  
  <p>2.What if there are too many <strong>Entry</strong> s for an <strong>Inventory</strong> and I have to load all of them when add an new <strong>Entry</strong>?</p>
  
  <p>I know these questions stem from lacking full understanding. So any idea is welcome, thanks in advance. </p>