First ask: if two ran at once, what breaks?
Wasted work means an efficiency lock: a cheap one is fine. Corrupted data means a correctness lock: no lock on its own is enough.
Why not a lock that never expires, so nobody can take it?
The catch
A crashed holder would block everyone forever. So every lock is a lease, and nothing stops the holder when it expires.
A 36-second GC pause outlasts a 30-second lease
Client 2 takes the expired lock and writes v2. Client 1 wakes, never told, and writes back its stale copy. v2 is silently lost.
Check the lock right before writing?
Bad: Check, then write
The pause can strike between the check and the write.
Good: Storage checks the writer
Only the resource, checking at write time, sees the true order.
Number every lease. Storage refuses anything older.
Each grant carries a fencing token larger than any before. Storage keeps the highest it accepted and refuses lower ones, so the late writer does no damage.
Redlock: five Redis primaries, lock by majority vote. Safe for correctness?
The verdict
No. It has no ordered token, and a clock jump or unsafe restart can grant overlapping leases.
Pick the tool by what a double run breaks
Only wasted work ends at a lock alone. For correctness, something that owns the data must check the holder.
The line to say
Every lock is a lease. Wasted work? One Redis key. Wrong data? Fence every write, or let the database guard its rows.