在存储过程中实现咨询锁

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$

根据 the documentation:

在程序开始时,获取独占咨询锁:

SELECT pg_advisory_lock(4711);

紧接在结束之前,释放锁:

SELECT pg_advisory_unlock(4711);

数字 4711 是一个随机数,重要的是您没有在其他任何地方使用相同的咨询锁号。

那么该函数的第二次并发执行将在尝试获取建议锁时阻塞,只有在释放锁时才允许继续执行。