Business Domain

In the Sales domain, I have 3 entities - Lead, Contact and Opportunity. A lead is injected into the system from many sources and nurtured. If it is a prospect then it is converted into a contact and opportunity(potential future sale). A contact represents the physical person in the CRM.

Problem Statement

An api convertLead which converts a lead by

  1. creating a contact
  2. creating an opportunity
  3. marking the lead as converted

Domain Model

In my model, lead, contact and opportunity are different aggregates.

Hence I need to perform a business transaction across 3 aggregates. The problem is I need my api to be sync - that is the response is received in the api, as this api will be exposed to 3rd party, hence I cannot make this business transaction eventually consistent. All Sales CRMs provide sync apis. How do I provide such an api? I am using Domain Driven Design to model my system and Lagom framework for implementing it.

Possible Solutions

  1. Do a polling on server side to provide a sync response and keep the transaction eventually consistent
  2. I do the coordination /flow in the service layer itself, taking a temporary lock on lead aggregate, and performing the business transaction. In case of failure(due to application down etc), the api could not complete execution and the lock will become invalid as it was temporary(lock valid for some seconds). This transient state is to handle parallel transactions(eg. deleteLead). Within the transaction, if due to application failure the api does not complete then the transaction will remain incomplete. In this use case the incomplete transaction is OK business wise. The user will just have to resend the command
  3. In some use cases, like pick a lead(i.e assign the lead to self), the transaction involves 2 aggregates - lead and userResource aggregate. I have 2 microservices, one managing lead and one managing resource assignment( like the number of leads a user can work on in a territory, finding the best rep for a lead, etc). Here I need the complete transaction to execute or nothing. In this case if I use the above method, I will need to make the system eventually consistent also (apart from flow logic in api) by implementing a saga which finds resource assignment aggregates in blocked state and frees them.

Solution 2 and 3 don't seem a very natural/recommended way. Also there is an overhead with modeling too many transient states. Please recommend what pattern people use to guarantee consistency with sync apis.

  • This is a problem where the solution seems apparent (you know the answer as well). If your business necessitates immediate consistency between multiple Aggregates, then they must be stored in a way such that they can be modified in a single transaction. Eventual consistency (EC) should only be employed after a thorough analysis of your requirements in terms of scaling (as this is the only advantage it gleans), and should not be made lightly as EC bestows far greater complexity upon an application. DDD is a design methodology that has nothing to say about database transactions. – king-side-slide Nov 21 '18 at 17:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.