在存储过程中实现咨询锁
Implement advisory lock inside stored procedure
我有一个如下所示的 stored procedure
,它是每 15 分钟 从 postgres cron
触发的 运行。通常情况下,这个 过程 需要更多时间才能完成。在这种情况下,当实现下一个时间表并再次调用程序时,我希望程序仍被调用,但要等到上一个完成。我怎样才能在不丢失任何新过程调用的情况下实现这一点?我听说这可以通过使用 advisory lock
来实现,但是我不确定我应该如何准备我的 程序 来实现这样的功能。任何人都可以告诉我如何准备我的程序吗?
我的存储过程:
CREATE OR REPLACE PROCEDURE public.test_procedure(p1 integer,
INOUT p2 character varying)
LANGUAGE plpgsql
AS $procedure$
DECLARE
loop_var int;
BEGIN
IF p1 is null OR p2 is null THEN
RAISE EXCEPTION 'input cannot be null';
END IF;
DROP TABLE if exists test_table;
CREATE TEMP TABLE test_table(a int, b varchar);
FOR loop_var IN 1..p1 LOOP
insert into test_table values (loop_var, p2);
p2 := p2 || '+' || p2;
END LOOP;
END;
$procedure$
修改后的程序:
CREATE OR REPLACE PROCEDURE public.test_procedure(p1 integer,
INOUT p2 character varying)
LANGUAGE plpgsql
AS $procedure$
DECLARE
loop_var int;
BEGIN
SELECT pg_advisory_lock(4711);
IF p1 is null OR p2 is null THEN
RAISE EXCEPTION 'input cannot be null';
END IF;
DROP TABLE if exists test_table;
CREATE TEMP TABLE test_table(a int, b varchar);
FOR loop_var IN 1..p1 LOOP
insert into test_table values (loop_var, p2);
p2 := p2 || '+' || p2;
END LOOP;
SELECT pg_advisory_unlock(4711);
END;
$procedure$
在程序开始时,获取独占咨询锁:
SELECT pg_advisory_lock(4711);
紧接在结束之前,释放锁:
SELECT pg_advisory_unlock(4711);
数字 4711 是一个随机数,重要的是您没有在其他任何地方使用相同的咨询锁号。
那么该函数的第二次并发执行将在尝试获取建议锁时阻塞,只有在释放锁时才允许继续执行。
我有一个如下所示的 stored procedure
,它是每 15 分钟 从 postgres cron
触发的 运行。通常情况下,这个 过程 需要更多时间才能完成。在这种情况下,当实现下一个时间表并再次调用程序时,我希望程序仍被调用,但要等到上一个完成。我怎样才能在不丢失任何新过程调用的情况下实现这一点?我听说这可以通过使用 advisory lock
来实现,但是我不确定我应该如何准备我的 程序 来实现这样的功能。任何人都可以告诉我如何准备我的程序吗?
我的存储过程:
CREATE OR REPLACE PROCEDURE public.test_procedure(p1 integer,
INOUT p2 character varying)
LANGUAGE plpgsql
AS $procedure$
DECLARE
loop_var int;
BEGIN
IF p1 is null OR p2 is null THEN
RAISE EXCEPTION 'input cannot be null';
END IF;
DROP TABLE if exists test_table;
CREATE TEMP TABLE test_table(a int, b varchar);
FOR loop_var IN 1..p1 LOOP
insert into test_table values (loop_var, p2);
p2 := p2 || '+' || p2;
END LOOP;
END;
$procedure$
修改后的程序:
CREATE OR REPLACE PROCEDURE public.test_procedure(p1 integer,
INOUT p2 character varying)
LANGUAGE plpgsql
AS $procedure$
DECLARE
loop_var int;
BEGIN
SELECT pg_advisory_lock(4711);
IF p1 is null OR p2 is null THEN
RAISE EXCEPTION 'input cannot be null';
END IF;
DROP TABLE if exists test_table;
CREATE TEMP TABLE test_table(a int, b varchar);
FOR loop_var IN 1..p1 LOOP
insert into test_table values (loop_var, p2);
p2 := p2 || '+' || p2;
END LOOP;
SELECT pg_advisory_unlock(4711);
END;
$procedure$
在程序开始时,获取独占咨询锁:
SELECT pg_advisory_lock(4711);
紧接在结束之前,释放锁:
SELECT pg_advisory_unlock(4711);
数字 4711 是一个随机数,重要的是您没有在其他任何地方使用相同的咨询锁号。
那么该函数的第二次并发执行将在尝试获取建议锁时阻塞,只有在释放锁时才允许继续执行。