Optimistic locking assumes conflicts are rare, so it takes no lock while working. Instead it records a version number or timestamp on read and, at write time, checks that the row has not changed since — if it has, the write is rejected and the caller retries.
Worked example: UPDATE … SET …, version = 6 WHERE id = 42 AND version = 5 — the update succeeds only if the row is still at version 5; if someone else bumped it to 6 first, zero rows update and you retry with fresh data. Gotcha: optimistic locking shines under low contention (no lock overhead) but wastes work under high contention (many retries), which is exactly where pessimistic locking — take the lock up front — wins; choose based on how often writes actually collide.