Advisory locks in PostgreSQL - Time & Space Complexity
Start learning this pattern below
Jump into concepts and practice - no test required
When using advisory locks in PostgreSQL, it's important to understand how the time to acquire or release a lock changes as more locks are requested.
We want to know how the system behaves when many sessions try to get advisory locks at the same time.
Analyze the time complexity of acquiring and releasing advisory locks.
-- Acquire an advisory lock with a key
SELECT pg_advisory_lock(12345);
-- Do some work while holding the lock
-- Release the advisory lock
SELECT pg_advisory_unlock(12345);
This code acquires a lock identified by a key, does some work, then releases the lock.
Look for repeated actions that affect performance.
- Primary operation: Checking and managing lock state in the lock manager.
- How many times: Each lock request involves searching the lock table, which grows with the number of active locks.
As more sessions request advisory locks, the system must check existing locks to avoid conflicts.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 checks |
| 100 | About 100 checks |
| 1000 | About 1000 checks |
Pattern observation: The number of operations grows roughly in direct proportion to the number of active locks.
Time Complexity: O(n)
This means the time to acquire or release a lock grows linearly with the number of locks currently held.
[X] Wrong: "Acquiring an advisory lock always takes the same time no matter how many locks exist."
[OK] Correct: The system must check existing locks to avoid conflicts, so more locks mean more work and longer wait times.
Understanding how advisory locks scale helps you design systems that handle concurrency well and avoid bottlenecks.
"What if advisory locks were replaced with session-level locks that do not check other locks? How would the time complexity change?"
Practice
Solution
Step 1: Understand advisory locks concept
Advisory locks allow applications to coordinate access to resources by using custom keys, not automatic locks on tables or rows.Step 2: Compare options
The other options describe other database features unrelated to advisory locks.Final Answer:
To control access to resources using user-defined keys -> Option AQuick Check:
Advisory locks = user-defined resource control [OK]
- Confusing advisory locks with automatic table locks
- Thinking advisory locks speed up queries
- Assuming advisory locks handle backups
Solution
Step 1: Recall advisory lock syntax
PostgreSQL uses the function pg_advisory_lock(key) to acquire a session-level advisory lock.Step 2: Evaluate options
SELECT pg_advisory_lock(12345); is the correct function call. The other options use invalid syntax or non-existent functions.Final Answer:
SELECT pg_advisory_lock(12345); -> Option AQuick Check:
pg_advisory_lock(key) = correct syntax [OK]
- Using LOCK TABLE instead of function call
- Calling non-existent functions like acquire_lock
- Trying to lock with BEGIN LOCK syntax
SELECT pg_try_advisory_lock(999);
Solution
Step 1: Understand pg_try_advisory_lock behavior
This function tries to acquire the lock immediately and returns true if successful, false if the lock is held by someone else.Step 2: Analyze the scenario
Since the lock with key 999 is already held, the function returns false without waiting.Final Answer:
false -> Option BQuick Check:
pg_try_advisory_lock returns false if lock busy [OK]
- Expecting true even if lock is held
- Thinking it returns null or error
- Confusing pg_try_advisory_lock with pg_advisory_lock
SELECT pg_advisory_unlock(123);
But the lock was never acquired before. What will happen?
Solution
Step 1: Understand pg_advisory_unlock behavior
This function releases a lock if held and returns true; if no lock was held, it returns false.Step 2: Analyze the scenario
Since the lock was never acquired, the function returns false without error or blocking.Final Answer:
The function returns false because no lock was held -> Option DQuick Check:
Unlock returns false if lock not held [OK]
- Expecting an error when unlocking unheld lock
- Thinking unlock blocks or waits
- Assuming unlock always returns true
-- Session 1 and 2 run this code:
SELECT pg_try_advisory_lock(42);
-- If true, run critical section, then
SELECT pg_advisory_unlock(42);
Solution
Step 1: Understand locking strategies
pg_try_advisory_lock returns immediately and may skip critical section if lock busy; pg_advisory_lock waits until lock is free.Step 2: Choose best approach for critical section
To ensure only one session runs critical section at a time, waiting for the lock is safer than skipping it.Step 3: Evaluate other options
Unlocking before acquiring is unsafe and random keys defeat locking purpose.Final Answer:
Use pg_advisory_lock to wait until lock is available before running -> Option CQuick Check:
Waiting lock ensures exclusive access [OK]
- Using try lock and skipping critical section silently
- Unlocking before locking without owning lock
- Using random keys causing no real locking
