postgresql/src/test/regress/sql/advisory_lock.sql
Itagaki Takahiro 62c7bd31c8 Add transaction-level advisory locks.
They share the same locking namespace with the existing session-level
advisory locks, but they are automatically released at the end of the
current transaction and cannot be released explicitly via unlock
functions.

Marko Tiikkaja, reviewed by me.
2011-02-18 14:05:12 +09:00

146 lines
4 KiB
PL/PgSQL

--
-- ADVISORY LOCKS
--
BEGIN;
SELECT
pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2),
pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2);
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
-- pg_advisory_unlock_all() shouldn't release xact locks
SELECT pg_advisory_unlock_all();
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';
-- can't unlock xact locks
SELECT
pg_advisory_unlock(1), pg_advisory_unlock_shared(2),
pg_advisory_unlock(1, 1), pg_advisory_unlock_shared(2, 2);
-- automatically release xact locks at commit
COMMIT;
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';
BEGIN;
-- holding both session and xact locks on the same objects, xact first
SELECT
pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2),
pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2);
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
SELECT
pg_advisory_lock(1), pg_advisory_lock_shared(2),
pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2);
ROLLBACK;
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
-- unlocking session locks
SELECT
pg_advisory_unlock(1), pg_advisory_unlock(1),
pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2),
pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1),
pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2);
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';
BEGIN;
-- holding both session and xact locks on the same objects, session first
SELECT
pg_advisory_lock(1), pg_advisory_lock_shared(2),
pg_advisory_lock(1, 1), pg_advisory_lock_shared(2, 2);
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
SELECT
pg_advisory_xact_lock(1), pg_advisory_xact_lock_shared(2),
pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock_shared(2, 2);
ROLLBACK;
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
-- releasing all session locks
SELECT pg_advisory_unlock_all();
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';
BEGIN;
-- grabbing txn locks multiple times
SELECT
pg_advisory_xact_lock(1), pg_advisory_xact_lock(1),
pg_advisory_xact_lock_shared(2), pg_advisory_xact_lock_shared(2),
pg_advisory_xact_lock(1, 1), pg_advisory_xact_lock(1, 1),
pg_advisory_xact_lock_shared(2, 2), pg_advisory_xact_lock_shared(2, 2);
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
COMMIT;
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';
-- grabbing session locks multiple times
SELECT
pg_advisory_lock(1), pg_advisory_lock(1),
pg_advisory_lock_shared(2), pg_advisory_lock_shared(2),
pg_advisory_lock(1, 1), pg_advisory_lock(1, 1),
pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2);
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
SELECT
pg_advisory_unlock(1), pg_advisory_unlock(1),
pg_advisory_unlock_shared(2), pg_advisory_unlock_shared(2),
pg_advisory_unlock(1, 1), pg_advisory_unlock(1, 1),
pg_advisory_unlock_shared(2, 2), pg_advisory_unlock_shared(2, 2);
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';
-- .. and releasing them all at once
SELECT
pg_advisory_lock(1), pg_advisory_lock(1),
pg_advisory_lock_shared(2), pg_advisory_lock_shared(2),
pg_advisory_lock(1, 1), pg_advisory_lock(1, 1),
pg_advisory_lock_shared(2, 2), pg_advisory_lock_shared(2, 2);
SELECT locktype, classid, objid, objsubid, mode, granted
FROM pg_locks WHERE locktype = 'advisory'
ORDER BY classid, objid, objsubid;
SELECT pg_advisory_unlock_all();
SELECT count(*) FROM pg_locks WHERE locktype = 'advisory';