Introduction
Imagine multiple people trying to edit the same document at the same time without locking it. How can we make sure their changes don't overwrite each other? This is the problem optimistic concurrency control solves in databases.
Imagine a group of friends writing a shared story on separate sheets of paper. Each writes their part without checking others. Before combining, they check if any parts contradict. If yes, they rewrite their parts to fit together.
┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ Transaction │ │ Validation │ │ Commit │ │ Reads │──────▶│ Checks for │──────▶│ Writes Changes│ │ Data State │ │ Conflicts │ │ if Valid │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Conflict Found? │ │ │ └───────┬─────────┘ │ │ Yes/No │ │ │ │ │ ▼ │ │ ┌─────────────────┐ │ │ │ Rollback and │ │ │ │ Retry Needed │ │ │ └─────────────────┘
import threading import time class Data: def __init__(self): self.value = 0 self.version = 0 def read(self): return self.value, self.version def write(self, new_value, old_version): if self.version == old_version: self.value = new_value self.version += 1 return True else: return False data = Data() # Transaction function simulating optimistic concurrency control def transaction(name, new_value): value, version = data.read() print(f"{name} reads value {value} with version {version}") time.sleep(1) # Simulate work success = data.write(new_value, version) if success: print(f"{name} writes value {new_value} successfully") else: print(f"{name} detects conflict and retries") # Run two transactions concurrently thread1 = threading.Thread(target=transaction, args=("T1", 10)) thread2 = threading.Thread(target=transaction, args=("T2", 20)) thread1.start() thread2.start() thread1.join() thread2.join()