Explizite Locks können Race-Conditions verhindern, sind aber blockend.
Advisory locks sind nicht blockend, müssen dafür aber von der Software verarbeitet werden.
Im Grunde wird in der pg_locks ein BigInt gespeichert, den man abfragen kann.
Das Setzen und Abfragen eines Locks kann mit einem BigInt oder mit zwei Integern als ClassId und ObjId erfolgen. Wenn man nur die id einer Tabelle verwendet (würde dann als BigInt interpretiert), dann hätte eine zweite Tabelle mit der gleichen id ebenfalls einen Lock (wenn er abgefragt wird), was ja nicht gewollt sein kann.
Nimmt man eine Nummer für die Tabelle (customer) dann muss die ja irgendwo systemweit verwaltet werden. Postgres hat ja für alle Tabellen bereits eine OID vergeben, die sich dafür eignet.
Die Abfrage mit einem Cast ist einfacher, als die Postgres-Tabellen direkt abzufragen:
SELECT ‚customer‘::regclass::oid liefert die OID zurück. Wenn wir den Datensatz mit der id 17 sperren wollen, dann wäre folgender Query erforderlich:
SELECT pg_try_advisory_lock((SELECT 'customer'::regclass::oid)::integer, 17);
Zum Entsperren:
SELECT pg_advisory_unlock((SELECT 'customer'::regclass::oid)::integer, 17);
Um alle Advisory Locks zu löschen:
SELECT pg_advisory_unlock_all();
Um sich die vorhandenen Locks anzuzeigen:
SELECT * FROM pg_locks;