Prevent Race Conditions with Row Locking
Avoid overselling inventory and double-updates using transactions and lockForUpdate().
Race conditions happen when two requests try to update the same record at the same time. Example: two customers buy the last item. - Both requests read stock=1 - Both reduce stock to 0 - Result: you oversold ## Safe pattern: lock the row ```php use Illuminate\Support\Facades\DB; DB::transaction(function () use ($productId) { $product = DB::table('products') ->where('id', $productId) ->lockForUpdate() ->first(); if ($product->stock <= 0) { throw new Exception('Out of stock'); } DB::table('products') ->where('id', $productId) ->update(['stock' => $product->stock - 1]); }); ``` ## Sequence: how locking prevents conflicts ```mermaid sequenceDiagram participant A as Request A participant DB as Database participant B as Request B A->>DB: lockForUpdate(product) DB-->>A: row locked, stock=1 B->>DB: lockForUpdate(product) DB-->>B: waits (locked) A->>DB: update stock=0 A->>DB: commit (unlock) DB-->>B: lock granted, stock=0 ``` In the next tutorial, we will learn indexing to speed up queries.