Note: Code examples in this article use Go. The concepts apply to any language.
Why lock at all?
Imagine two users trying to withdraw money from the same bank account simultaneously. Without proper synchronization, both might read the same balance, deduct their amounts independently, and write back—resulting in a lost update. One withdrawal effectively disappears.
This is a classic race condition, the correctness of the outcome depends on the timing of operations.