Use optimistic locking for most cases: give the row a version column or timestamp, include it in the update predicate, and if zero rows are updated the record changed underneath you, so you return a conflict. Use pessimistic locking, a select for update inside a short transaction, when conflicts are frequent or the operation cannot be retried safely. The one thing you must not do is read, modify and write with no check at all.
Why interviewers ask this
Lost updates are a silent data corruption class that never shows up in tests. The interviewer wants to see that you know the read modify write hazard, can pick a strategy based on contention rather than habit, and understand the user experience consequences: optimistic locking means someone gets an error and must merge, pessimistic locking means someone waits and you now own lock lifetime and deadlock risk.
How to structure your answer
- Name the hazard first: read modify write without a guard.
- Describe optimistic locking mechanically, including the zero rows check.
- Say when contention justifies pessimistic locking.
- Cover what the user sees in a conflict.
Example answer
The failure is read modify write, where both requests load version one, both compute from stale data and the second write wins silently. My default fix is optimistic: every row has a version, the update says where id equals this and version equals what I read, and it bumps the version. If the update reports zero rows changed, someone else got there first and I return a 409 rather than pretending it worked. That costs nothing when conflicts are rare, which they usually are. I switch to pessimistic locking when contention is real or a retry is unacceptable, for example decrementing inventory, where I take a select for update on the row, do the check and the write in one short transaction, and keep no network calls inside that transaction. The part I care about most is what the user sees. A raw conflict error is useless, so for a document editor we returned the current version alongside the error so the client could show a diff instead of just losing the work.
Walking into this interview soon? GhostPilot listens to your live call, spots the question the moment it is asked, and puts a structured answer on your screen in real time. Try it on your next mock, or grab a $29 Session Pass, no subscription, for the real thing.
See how it worksFollow-up questions to expect
- How would you expose a conflict through your HTTP API?
- What are the risks of holding a select for update across a service call?
- How does an ETag with if match relate to optimistic locking?
Related backend developer questions
Your interviewer will ask their own version of this. Paste your actual job description into the free Question Predictor and get the 20 questions that role is most likely to ask, with what each one is really probing.
Predict my questions