The tech fest registration system is now popular.
But a bug appears.
Two students manage to register for the last seat of an event.
How did that happen?
Race conditions
Imagine there is one seat left.
Two workers check the database simultaneously.
Worker 1 → seats_available = 1
Worker 2 → seats_available = 1
Both proceed to reserve the seat.
Now the event is overbooked.
This problem is called a race condition. Multiple processes race to update the same resource.
Using locks
A lock ensures only one worker accesses a critical section at a time.
Worker A acquires lock
↓
Checks seat count
↓
Reserves seat
↓
Releases lock
Worker B must wait until the lock is released.
The worker that gets the lock first wins.
Implementing locks in Python
import redis
redis_client = redis.Redis()
def reserve_seat(event_id, student_id):
lock_key = f"lock:event:{event_id}"
# Try to acquire lock
lock = redis_client.lock(lock_key, timeout=5)
if lock.acquire(blocking=True):
try:
# Critical section
seats = get_available_seats(event_id)
if seats > 0:
save_registration(event_id, student_id)
return True
return False
finally:
lock.release()
Redis locks work across multiple workers because Redis is a shared resource.
Database-level locks
Databases also provide locking mechanisms.
SELECT * FROM events
WHERE event_id = 123
FOR UPDATE;
The FOR UPDATE clause locks the row until the transaction completes.
Other workers trying to read that row will wait.
Atomic writes
Another issue appears when writing data.
Suppose the server crashes while writing a file.
The file may look like this:
{
"name": "Rahul",
"email":
This is a partial write.
To prevent corruption, systems use atomic writes.
Instead of writing directly to the final file:
registrations.json
We write to a temporary file:
registrations.tmp
Then rename it:
registrations.tmp → registrations.json
File renaming is atomic, meaning the file appears completely or not at all.
Atomic writes in Python
import os
import json
def save_registration_safely(data):
temp_file = "registrations.tmp"
final_file = "registrations.json"
# Write to temp file
with open(temp_file, 'w') as f:
json.dump(data, f)
# Atomic rename
os.replace(temp_file, final_file)
Database transactions
Databases handle atomicity through transactions.
BEGIN TRANSACTION;
UPDATE events SET seats_available = seats_available - 1
WHERE event_id = 123;
INSERT INTO registrations (student_id, event_id)
VALUES (456, 123);
COMMIT;
Either both operations succeed, or both fail. There is no partial state.
But backend systems interact with external services too.
And external systems fail.
That introduces the next challenge.