PostgreSQL raises lock_not_available (SQLSTATE 55P03) when a session cannot immediately obtain a requested lock because another transaction still holds it.
lock_not_available (SQLSTATE 55P03) means your PostgreSQL query tried to take a lock that another session already owns, and the NOWAIT clause or lock timeout blocked waiting. Remove NOWAIT, increase lock_timeout, or reorder transactions so the first one commits before the second needs the lock.
lock_not_available
PostgreSQL throws lock_not_available
when a transaction requests a lock that cannot be granted immediately. The server returns SQLSTATE 55P03 instead of waiting when the statement uses NOWAIT
or when lock_timeout
expires.
The error prevents a query from hanging indefinitely but also aborts the current statement.
Understanding why the lock is busy and how to coordinate concurrent sessions is critical for high-throughput systems.
The error appears when a conflicting lock already exists on the same relation, row, or advisory lock object. PostgreSQL refuses to queue the request because the client asked not to wait.
Typical triggers include SELECT ... FOR UPDATE NOWAIT
, LOCK TABLE ...
IN EXCLUSIVE MODE NOWAIT
, or any statement issued while lock_timeout
is active and low.
Increase lock_timeout
or drop the NOWAIT
keyword so PostgreSQL can wait for the lock.
Commit or roll back the blocking transaction from the other session, or terminate it with pg_terminate_backend()
if it is stuck.
Long-running batch job blocks OLTP queries – Move the batch to off-hours or break it into smaller transactions.
Frequent schema migrations – Use LOCK TABLE ...
SHARE UPDATE EXCLUSIVE
instead of ACCESS EXCLUSIVE to reduce conflicts.
Keep transactions short, acquire locks in a consistent order, and set a realistic lock_timeout
to fail fast during deadlock-prone operations.
Monitor pg_stat_activity for blocking PIDs and pg_locks for lock types. Automate alerts when wait times spike.
deadlock_detected (40P01)
indicates circular lock dependencies; resolve by reordering statements.
serialization_failure (40001)
occurs under SERIALIZABLE isolation; retry the whole transaction.
.
No. The error fires before a deadlock forms because the client asked not to wait. Deadlocks raise 40P01 instead.
Usually yes, but long waits can harm user experience. Combine higher lock_timeout with monitoring.
Galaxy’s editor highlights blocking queries in real time and lets you terminate or refactor them before rerunning, reducing accidental NOWAIT conflicts.
No. That parameter controls lock array sizing, not lock contention. Focus on shorter transactions and ordered locking.