嵌套存储过程的增量进展(Postgres)

Incremental progress on nested stored procedure (Postgres)

我有三个按顺序 运行 的 Postgres 存储过程(即 SP1 将调用 SP2,然后调用 SP3)。在处理这些嵌套存储过程时,我注意到只有在最后一个存储过程完成 (SP3) 之后我才能看到 SP1 的结果。

有没有办法在执行时产生这些过程的结果,而不是等待所有过程完成?

谢谢!

部分代码供参考:

create or replace procedure sp1()
as $$

declare

begin
    
    drop table if exists seq_test;
    create table seq_test (
        step        varchar,
        status      varchar,
        time_log    timestamp not null default now()
    );
    
    insert into seq_test values ('1','running','now');
    raise notice 'step 1 beginning';
    
    -- does something

    insert into seq_test values ('1','complete','now');
    raise notice 'step 1 complete';
    
    call sp2(); 
        
end;
$$
language plpgsql;

--------------

create or replace procedure sp2()
as $$

declare

begin
    
    insert into seq_test values ('2','running','now');
    raise notice 'step 2 beginning';
    
    -- does something else

    insert into seq_test values ('2','complete','now');
    raise notice 'step 2 complete';
    
    call sp3(); 

end;
$$
language plpgsql;

--------------

create or replace procedure sp3()
as $$

declare

begin
    
    insert into seq_test values ('3','running','now');
    raise notice 'step 3 beginning';
    
    -- does something else

    insert into seq_test values ('3','complete','now');
    raise notice 'step 3 complete';
        
end;
$$
language plpgsql;

--------------------------------------------------

call sp1();

在上面的脚本中,如果假设每个 SP 需要 1 分钟才能完成,尽管在整个 3 分钟的运行时间中记录被插入 seq_test 我实际上不会能够观察到这些记录,直到每个SP都完成。

您看不到结果,因为数据修改只有在进行修改的事务结束后才可见。这是由默认的 READ COMMITTED 事务隔离级别保证的,在 PostgreSQL 中没有办法获得“脏读”。

默认情况下,CALL sp1() 将在单个事务中 运行,这解释了您观察到的情况。

您可以通过在存储过程中显式调用 COMMIT AND CHAIN 来更改该行为。这将提交到目前为止的工作并开始一个新的事务。但考虑后果:如果执行遇到错误,事务将被回滚(撤销)。程序中间的 COMMIT 可能导致只完成部分工作。这可能正是您所需要的,但通常是不希望的。