I'm currently building my first ever microservice using NodeJS, but I stumbled upon a problem.
TL;DR ~ How to ensure data consistency between 2 microservices while both having write permissions
I currently have 2 independent microservices: session & recovery
- Session: Handles authentication (sign up, sign in, sign out, current user)
- Recovery: Handles password resets (request a reset, reset the password)
Both services contain an identical copy of the user table. Every record has a
version field to ensure data consistency.
I'm using a message broker (NATS) in between the 2 services.
A brief example of how the application flow works.
Let's say we want to do a password reset: Recovery Service:
- Request password reset
- Generate token
- Specify new password (legitimized by token)
- Increase the version of the user
- Receives event with data (user id, user version, new password)
- Search for a user with specified
version - 1
- Found? Update the password
- Increase version number
- The recovery service doesn't hold all the user data. In fact, it's only used to check if the user exists.
- The password is not stored inside the recovery service, it's send to the session service via the
These are the 2 tables inside the recovery service:
- Recovery table: Contains the user reference , a generated token, the status (pending, expired, completed)
- User table: Contains the user id and the user its version
This works fine, but what if you update the same user simultaneously in both services?
What if 2 microservices, that hold a copy of the same table, both modify different a property at the same time?
- Recovery service handles password modification for a user
- Session service handles all other modifications for a user (first name, last name,...)
They will both, at the same time, modify their tables. Therefor increase the version count and then emit an event to the other services. When the
UserUpdateEvent is received by the other services it won't be recognized as a 'legit' event since there is a version mismatch between
- Does this mean I should have kept this functionality in one service?
- Perhaps only one service should be able to modify a table?
- Maybe I shouldn't keep a version inside the recovery table at all?
Hopefully a more experienced person can help me out!