Advisory Locks
Application-level, cooperative locks managed by the database engine but with semantics entirely controlled by the application.
advisory lock pg_advisory_lock GET_LOCK DBMS_LOCK app lock named lock sp_getapplock
locking advisory cooperative application lock named lock concurrency
| Database | Status | Syntax Family | Min Version |
|---|---|---|---|
| PostgreSQL | full | sql-standard | - |
| MySQL | full | get-lock | - |
| MariaDB | full | get-lock | - |
| Oracle | full | dbms-lock | - |
| SQL Server | full | sp-getapplock | - |
| SQLite | none | - | - |
| Redshift | none | - | - |
| DB2 | none | - | - |
| Snowflake | none | - | - |
| BigQuery | none | - | - |
Compare Databases
Database Details
PostgreSQL
full
-- Session-scoped exclusive lock (blocks until acquired)
SELECT pg_advisory_lock(12345);
-- ... critical section ...
SELECT pg_advisory_unlock(12345);
-- Transaction-scoped (auto-released on COMMIT/ROLLBACK)
BEGIN;
SELECT pg_advisory_xact_lock(12345);
-- ... critical section ...
COMMIT;
-- Non-blocking try variant
SELECT pg_try_advisory_lock(12345); -- returns boolean
-- Shared lock variant
SELECT pg_advisory_lock_shared(12345);
-- View all current advisory locks
SELECT * FROM pg_locks WHERE locktype = 'advisory';- Keys are one bigint or two int4s; the meaning is entirely up to the application.
- Session-scoped locks live until released or the session ends. The _xact_ variants release automatically on COMMIT or ROLLBACK.
- Exclusive and shared modes coexist, and pg_try_advisory_lock returns false instead of blocking.
- Inspect holders via pg_locks WHERE locktype = 'advisory'.
MySQL
full
-- Acquire named lock (timeout in seconds; 0 = immediate, -1 = infinite)
SELECT GET_LOCK('my_app_lock', 10); -- returns 1 (success), 0 (timeout), NULL (error)
-- Release lock
SELECT RELEASE_LOCK('my_app_lock');
-- Check if lock is free
SELECT IS_FREE_LOCK('my_app_lock');
-- Get connection ID of lock holder
SELECT IS_USED_LOCK('my_app_lock');- Lock name is any string up to 64 characters. Since 5.7 a session can hold many at once.
- Timeout is in seconds: 0 is try-once, -1 waits forever.
- Locks release on RELEASE_LOCK or when the session closes. IS_USED_LOCK returns the holder's connection_id or NULL.
Docs: Locking Functions
MariaDB
full
SELECT GET_LOCK('my_app_lock', 10);
-- ... critical section ...
SELECT RELEASE_LOCK('my_app_lock');- Same GET_LOCK / RELEASE_LOCK / IS_FREE_LOCK API and session-scoped semantics as MySQL.
Docs: GET_LOCK
Oracle
full
DECLARE
l_handle VARCHAR2(128);
l_result INTEGER;
BEGIN
-- Allocate a named lock handle
DBMS_LOCK.ALLOCATE_UNIQUE('my_app_lock', l_handle);
-- Request exclusive lock (timeout 10 seconds)
l_result := DBMS_LOCK.REQUEST(
lockhandle => l_handle,
lockmode => DBMS_LOCK.X_MODE,
timeout => 10
);
-- ... critical section ...
-- Release
l_result := DBMS_LOCK.RELEASE(l_handle);
END;
/- Requires EXECUTE on DBMS_LOCK (or DBMS_SESSION on newer versions).
- DBMS_LOCK.ALLOCATE_UNIQUE maps a string name to a numeric handle you then REQUEST and RELEASE.
- Six modes: NULL, SS, SX, S, SSX, X.
- Oracle 20c and later steer new code toward DBMS_SESSION.ACQUIRE_UNIQUE_TAGGED_LOCK.
Docs: DBMS_LOCK
SQL Server
full
-- Session-scoped application lock
DECLARE @result INT;
EXEC @result = sp_getapplock
@Resource = 'my_app_lock',
@LockMode = 'Exclusive',
@LockOwner = 'Session',
@LockTimeout = 10000; -- milliseconds
-- ... critical section ...
EXEC sp_releaseapplock
@Resource = 'my_app_lock',
@LockOwner = 'Session';
-- Return values: 0=granted, 1=granted after wait, -1=timeout, -2=cancelled, -3=deadlock- sp_getapplock and sp_releaseapplock acquire and release a named lock; the resource name is any string.
- LockOwner 'Session' survives transaction boundaries; 'Transaction' releases at COMMIT or ROLLBACK.
- Modes: Shared, Update, Exclusive, IntentShared, IntentExclusive. Return >= 0 on success, < 0 on timeout/deadlock/cancel.
Docs: sp_getapplock
SQLite
none
- No advisory lock API. SQLite uses OS file locks internally, but those are not exposed to SQL.
- Coordinate cross-process work outside the database (file locks, OS mutexes, an external store).
Redshift
none
- No advisory lock API. LOCK TABLE serializes at the table level but is a blunt instrument.
- For cross-session coordination, reach for DynamoDB or ElastiCache.
Docs: Amazon Redshift LOCK
DB2
none
- No general-purpose advisory lock API.
- Approximations: LOCK TABLE for table-level serialization, SELECT ... FOR UPDATE or WITH RR for row-level pessimistic locking.
Snowflake
none
- No advisory lock API. Coordination between sessions is optimistic at the storage layer; application locks belong in an external store.
Docs: Transactions
BigQuery
none
- No advisory lock API. Transactions are optimistic with fixed snapshot isolation; reach for Firestore or Spanner for cross-session locks.
Docs: BigQuery Transactions