gotchaCriticalpending
Gotcha: Race conditions in distributed systems with check-then-act
Viewed 0 times
toctourace conditioncheck then actatomic operationselect for update
Error Messages
Problem
Code that checks a condition then acts on it is vulnerable to race conditions when multiple processes/threads are involved.
Solution
Check-then-act race conditions and fixes:
Fixes by context:
General principle: Make the check and action a single atomic operation. Use database constraints, atomic instructions, or locks.
## The pattern (TOCTOU - Time Of Check vs Time Of Use):
1. Check: Is the seat available?
2. (Another request books the seat)
3. Act: Book the seat -> DOUBLE BOOKING!
## In code:
# BAD: Check then act (race condition)
if inventory.count > 0: # Check
inventory.count -= 1 # Act (another thread may have decremented!)
create_order(item)
# BAD: Check file exists then read
if os.path.exists(file): # Check
data = open(file).read() # Act (file may be deleted between check and open)Fixes by context:
-- Database: Use atomic operations
-- BAD:
SELECT stock FROM products WHERE id = 1; -- stock = 5
UPDATE products SET stock = 4 WHERE id = 1;
-- GOOD: Atomic update with condition
UPDATE products SET stock = stock - 1
WHERE id = 1 AND stock > 0
RETURNING stock;
-- If no rows updated, stock was 0
-- GOOD: SELECT FOR UPDATE (row-level lock)
BEGIN;
SELECT stock FROM products WHERE id = 1 FOR UPDATE;
-- Row is locked, other transactions wait
UPDATE products SET stock = stock - 1 WHERE id = 1;
COMMIT;# Redis: Use atomic operations
import redis
r = redis.Redis()
# Atomic decrement with check
result = r.decr('inventory:item:123')
if result < 0:
r.incr('inventory:item:123') # Roll back
raise OutOfStock()
# Or use Lua script for complex atomic opsGeneral principle: Make the check and action a single atomic operation. Use database constraints, atomic instructions, or locks.
Why
Any time you check then act in separate steps, another process can change the state between your check and your action. The only safe approach is to make check+act atomic.
Context
Concurrent and distributed systems
Revisions (0)
No revisions yet.