We have a set of micro-services that are functionally dependent and have intertwined validation logic. e.g. consider 'Credit-Card' service and 'Loan' service. When user has a credit card then loan shouldn't be given and vice versa. Hence when processing a request we validate across these services using API calls and consider approval of the request. How to handle scenarios when both are initiated simultaneously in distributed systems.

How do we prevent a customer from getting both loan and a credit card at the same time. I am considering using distributed locks to implement a solution. Would like to know if there are other possibilities apart from locks.

  • Is the question "How to prevent a customer from obtaining a loan and a credit card at the same time" ? Please state the expected behavior.
    – Martin K
    Commented Jan 4, 2020 at 9:25
  • @MartinK, yes that is the state required. Added it the question for visibility for others as well.
    – Sekar
    Commented Jan 4, 2020 at 9:30

2 Answers 2


This kind of issue is common in distributed systems. The simplest solution is to combine the check for whether a change is allowed with the request to make the change. This technique is useful in a number of contexts. For example, let's forget the loan for a second and just focus on the credit card. Let's say you have a table that contains active credit card applications and you have multiple instances of the service running. You want to prevent someone from having two active applications at the same time (e.g. they refresh the page and submit twice.) In the situation that the services are stateless, each submission could end up on a different instance of the service. Since one service has no idea what the other is doing, we have to look to the database to address this.

One approach is to do an insert or update conditionally. For example, you update the application state to active only if there count of active applications is zero. This is done as a single atomic statement on the DB. Then you check the number of record updated. If that is zero, that update was preempted, if it's something else, that call succeeded. This is kind of like optimistic locking which tends to be less problematic than pessimistic locking. Even if you use a pessimistic lock, the kind of approach I am describing needs to be used to acquire the lock. You might as well skip that extra layer and get to the point.

The situation with two different services is basically the same problem. The question is whether you distinct storage for each and whether they have strong consistency guarantees. In the case that you have separate DB solutions for each service (as would be expected in a microservice architecture) you might want to introduce a third service that acts as an arbitrator for such scenarios. This would allow you to choose storage with strong consistency guarantees as well.

Lastly, you need to balance the cost of this with the likelihood of it occurring. Would having some check after the fact be good enough? If it almost never comes up, contacting the customer to tell them their applications are both denied and they need to choose one might suffice from a business perspective.


I think you said it in your first sentence - the solution is made more complex when you have intertwined or distributed validation logic. My first step would be to refactor the validation logic into a customer validation service (for lack of better words). Most countries have rating services of sort, companies have internal blacklists and customer information held internally. Determining if we should do business with a customer is going to be a very similar task for most operations.

Now you will also have a time-of-check to time-of-use problem. A customer could pass both checks simultaneously whereas the desired behavior would be to deny the second check.

Ideally, we would like to avoid a transactional system across microservices. A first step would be to place a temporary hold on a customer validation check system at time of check. This does not a deterministic fix but would be a great first line of defense.

The check could issue a time-based OTP. This would close the loop as the password would only be good while the temporary block would deny further requests.

I found an interesting article that made a case for eventual consistency. Now the security of this approach depends on whether or not your process has another checkpoint before any privileges are given to the user. For example. credit cards needs to be printed and loans need to be processed. Can you afford to "approve" the loan or credit card, but not issue the card or funds, using the processing time to catch the policy failure?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.