Во время работы многопользовательской системы клиенты имеют право лететь в крэш, отваливаться по различным программно-техническим причинам. После этого в базе висят незавершенные транзакции и залипшие блокировки. Попробую составить приемлемый алгоритм для решение этой проблемы...
CREATE TABLE public."Locks" (
"Table" VARCHAR(128) NOT NULL,
"Record" INTEGER NOT NULL,
"User" INTEGER NOT NULL,
"Pid" INTEGER NOT NULL,
"Date" DATE NOT NULL,
"Time" TIME(6) WITHOUT TIME ZONE NOT NULL,
CONSTRAINT "Locks_idx" PRIMARY KEY("User", "Table", "Record")
) WITHOUT OIDS;
В нее будем записывать все блокировки. По полям это понятно:
Для этого по полю User ищем все свои "старые" PID и убиваем их:
SELECT pg_terminate_backend(pid);
Если временной штамп меньше заданного - ждем (делаем попытки захвата раз в N сек), если временной штамп больше заданного - пробуем убить чужую блокировку
подключенные соединения отлавливаем запросом
SELECT procpid FROM pg_stat_activity
убиваем чужие блокировки, если их PID'ы отсутствуют в списке подключенных
Все описанное справедливо для PostgreSQL > 9.x версии и наличии прав суперпользователя у подключаемого клиента.