Locks: Foundations of Concurrent Control


Three Problems Locks Solve ๐ŸŽฏ

3 Transactions (T1, T2, T3) doing some stock trading on X, Y accounts

๐Ÿšซ Problem 1: Correctness

Lost Updates

โŒ Without Locks:

T1: READ(x)=100
T2: READ(x)=100
T1: WRITE(x=150)
T2: WRITE(x=130) โŒ

โ†’ T1's update lost!

โœ… With Locks:

T1: LOCKโ†’READโ†’WRITEโ†’UNLOCK
T2: [waits]โ†’LOCKโ†’READ(150)โœ“

โฑ๏ธ Problem 2: Long Calculations

CPU Idle During Complex Logic

โŒ Serial Execution:

T1: Do 10 - 200,000 operations on data X
T2: Wait... then process data Y
T3: Wait... wait... then process data Z

โ†’ Only 1 CPU core used!

โœ… Parallel Execution:

T1: LOCK(X) โ†’ Process X
T2: LOCK(Y) โ†’ Process Y (parallel!)
T3: LOCK(Z) โ†’ Process Z (parallel!)

โ†’ All CPU cores utilized!

๐Ÿ’พ Problem 3: IO Lag

CPU Idle During Disk Access

Read Operations:
Rs = Read Start (CPUโ†’Disk)
Re = Read End (Diskโ†’CPU)
Gap = ~5ms of waiting

Write Operations:
Ws = Write Start (CPUโ†’Disk)
We = Write End (Disk confirms)
Gap = ~10ms of waiting

โœ… With Locks:
T2 uses CPU during T1's IO gaps


The Lock Cycle: How It Works ๐Ÿ”„

3 Transactions (T1, T2, T3) competing for 2 Concert Tickets (seat A, seat B)

Request-Get-Unlock cycle showing lock lifecycle

Key Insight: T1 and T3 can work simultaneously (different tickets), but T2 must wait for T1.

Legend: Operation Types

๐Ÿ”’ Locking Request, Get, Unlock operations
๐Ÿ’พ IO Disk reads/writes (Rsโ†’Re, Wsโ†’We)
๐Ÿงฎ Logic CPU computation on data

Step-by-Step Lock Lifecycle

During IO gaps (Rsโ†’Re), locks coordinate access between T1, T2, T3:

๐Ÿ”’ Locking

1๏ธโƒฃ Request

Transaction asks for lock on concert ticket

T1: REQ_LOCK(Ticket_A, lock)
T3: REQ_LOCK(Ticket_B, lock)
๐Ÿ”’ Locking

2๏ธโƒฃ Get

Lock manager checks who gets access

Got: T1 gets lock on Ticket_A
Waiting: T2 waits
๐Ÿ’พ IO + ๐Ÿงฎ Logic

3๏ธโƒฃ Use Data

Read ticket data (IO) then process purchase (Logic)

IO: Rsโ†’Re (fetch ticket price)
Logic: Calculate total, apply discount
๐Ÿ”’ Locking

4๏ธโƒฃ Unlock

Release lock so others can buy

T1: UNLOCK(Ticket_A) โ†’ T2 can now try
After: We (write confirmed)

Types of Locks: Why We Need Two Kinds ๐Ÿ”

The Opportunity: Reads vs Writes are Different

Key Insight: Reading doesn't change data, writing does. So we can optimize!

๐Ÿ“– Shared Lock (S-lock)

For Reading Data

Real Example: Checking Seat A-15 Availability

T1: S-LOCK(Seat_A15) โ†’ READ status = "available"
T2: S-LOCK(Seat_A15) โ†’ READ status = "available"
T3: S-LOCK(Seat_A15) โ†’ READ status = "available"

โœ… All can check availability simultaneously!
Everyone can look at the same seat's status at once without interfering.

โœ๏ธ Exclusive Lock (X-lock)

For Writing Data

Real Example: Purchasing Seat A-15

T1: X-LOCK(Seat_A15) โ†’ WRITE status = "sold to T1"
T2: [BLOCKED] Can't even check availability
T3: [BLOCKED] Can't check or buy

๐Ÿšซ Only one can buy (or even look) at a time!
During purchase, no one else can read OR write to prevent seeing partial updates.

Why This Design is Smart ๐Ÿง 

๐Ÿš€ Maximum Browsing

Multiple transactions can read the same data simultaneously (S + S = โœ…)

Example: 1000 customers can check seat A-15's availability at the same time

๐Ÿ›ก๏ธ Purchase Integrity

No transaction can read while another is writing (S + X = โŒ)

Example: When someone is buying seat A-15, others can't even check it (prevents seeing partial updates)

๐Ÿ”’ No Double-Booking

Only one transaction can write at a time (X + X = โŒ)

Example: Only one person can complete purchase of seat A-15

Lock Compatibility Matrix

๐Ÿ“– Shared (S) โœ๏ธ Exclusive (X)
๐Ÿ“– Shared (S) โœ… Compatible
Many readers OK
โŒ Conflict
No read during write
โœ๏ธ Exclusive (X) โŒ Conflict
No write during read
โŒ Conflict
Only one writer

Example: Bank Transfer with IO Timing

-- Transaction: Transfer $100 from Account A to Account B

BEGIN TRANSACTION
    -- Before Rs: Request locks
    LOCK_EXCLUSIVE(Account_A)  -- Granted instantly
    LOCK_EXCLUSIVE(Account_B)  -- Granted instantly

    -- Trigger Rsโ†’Re: Read operations
    READ balance_A FROM Account_A  -- Rs_A โ†’ ... โ†’ Re_A (balance_A = 500)
    READ balance_B FROM Account_B  -- Rs_B โ†’ ... โ†’ Re_B (balance_B = 200)

    -- Process data (CPU time)
    balance_A = balance_A - 100  -- Account_A = 400
    balance_B = balance_B + 100  -- Account_B = 300

    -- Trigger Wsโ†’We: Write operations  
    WRITE(Account_A, 400)  -- Ws_A โ†’ ... โ†’ We_A
    WRITE(Account_B, 300)  -- Ws_B โ†’ ... โ†’ We_B

    -- After We: Release locks
    UNLOCK(Account_A)
    UNLOCK(Account_B)
COMMIT

Key Point: During the Rsโ†’Re and Wsโ†’We gaps, other transactions can acquire locks on different accounts and make progress!