Laravel interview question · Most asked

How do you protect an endpoint against race conditions in Laravel, for example two users buying the last item?

Summary

Make the check and the write atomic: a conditional update (update ... where stock > 0), a row lock inside a transaction (lockForUpdate()), or a distributed lock (Cache::lock) for logic spanning several resources. Validation alone cannot prevent it.

Longer Answer

The naive version (read stock, check it, decrement) lets two requests read stock = 1 and both succeed. Options:

  • Atomic conditional update: Product::whereKey($id)->where('stock', '>', 0)->decrement('stock') returns the number of affected rows; 0 means sold out. Simple and fast.
  • Pessimistic lock: inside DB::transaction, Product::lockForUpdate()->find($id), then check and update. Other transactions wait for the lock.
  • Optimistic locking: a version column; update where version = ? and retry on conflict.
  • Cache locks for cross-resource critical sections, keeping the database constraint as the final guarantee.

Key Points

  • Read-check-write races without atomicity.
  • Conditional update is simplest.
  • lockForUpdate() inside a transaction.
  • Optimistic locking with a version column.

Deep dive: Transactions, Locking & Concurrency in Code

More most-asked Laravel questions

← All Laravel questions