Database lock

A temporary claim that makes conflicting database work wait, so two transactions do not change the same data at once.

stop two requests editing the same rowmake the second database writer waitthis row is busydatabse lockselect for updatetwo people bought the last item at the same timewhy is my query waiting on another transactionhold this row so no other worker grabs the job

See it

Live demo coming soon

What it is

A database lock is a temporary claim on data or a database resource that blocks incompatible work. Databases take many locks automatically while they read and write. You can also ask PostgreSQL for a row lock with SELECT ... FOR UPDATE when a transaction must read a row, make a decision, and update it without another writer slipping into the gap.

Reach for an explicit lock when several statements must act on the same hot row as one protected sequence: claim a queued job, reserve stock, or update a balance. FOR UPDATE SKIP LOCKED is useful for workers claiming different queue rows without waiting behind one another. That clause landed in PostgreSQL 9.5 and is the reason a whole generation of job queues, from graphile-worker to Rails Solid Queue, run on the main database instead of a separate Redis. Keep the transaction short because the lock normally lives until commit or rollback.

Gotcha: locks trade races for waiting, and inconsistent lock order can create a deadlock. If one transaction locks A then B while another locks B then A, the database must abort one of them. Lock rows in a consistent order, set a sensible lock timeout, retry deadlock victims, and never hold a transaction open while calling an external API.

Ask AI for it

Protect this PostgreSQL read-modify-write path with a row lock. Start a transaction, select the target rows with SELECT ... FOR UPDATE in a stable primary-key order, validate the invariant, write the changes, and commit before any network call. For competing queue workers, use FOR UPDATE SKIP LOCKED with LIMIT and process only the rows each worker claimed. Set lock_timeout, catch SQLSTATE 40P01 for deadlocks, and retry the whole transaction with bounded backoff. Add a two-connection test showing the second writer cannot overwrite the first.

You might have meant

database transactiontransaction isolationrace conditionoptimistic lockingjob queue