postgresql多功能事务控制

lmyy7pcs  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(1)|浏览(125)

我创建了4个postgresql mock up函数,以测试具有多个函数的事务控件,如下所示,

create table test
(
    text varchar(20)
);

create table log
(
    text varchar(20)
);

create or replace function test1
(
    p_data       in text,
    p_result     out text
)
as $$
begin

    insert into test (text)
    values(1);   

    p_result := '';                

exception
        when others then

          PERFORM log_entry
                (
                  'test1 error'
                );         
                
          p_result := '';  

end
$$ LANGUAGE plpgsql;

create or replace function test2
(
    p_data       in text,
    p_result     out text
)
as $$
begin

    insert into test (text)
    values(2);

    p_result := '';   

exception
        when others then
            
            PERFORM log_entry
                (
                  'test2 error'
                );
          
            p_result := '';     
           
end;
$$ LANGUAGE plpgsql;

create or replace function test3
(
    p_data       in text,
    p_result     out text
)
as $$
begin

    insert into test (text)
    values(3333333333333333333333333333333333333333333333333333333333333333333);

    p_result := ''; 

exception
        when others then

            PERFORM log_entry
                (
                  'test3 error'
                );
            
            p_result := '';  
end;
$$ LANGUAGE plpgsql;

create or replace function log_entry
(
    p_data       in text
)
returns void as $$
 
begin

    insert into log (text)
    values(p_data);

end;
$$ LANGUAGE plpgsql;

字符串
我调用函数的方式是,

DO $$ BEGIN

    PERFORM "test1"('');
    PERFORM "test2"('');
    PERFORM "test3"('');

END $$;


因此,当函数“test 3”被执行时,由于它试图插入到测试表中的数据太长而失败,我可以看到表测试有2行,值1和2;表日志有1行,值test 3错误。
我的问题是,
如果我想实现的是,回滚由函数test1和test 2完成的事务,但只提交日志条目(意味着表test应该是空的,表log应该有1行是test 3错误),怎么做?
注意事项:我不想将合并3个函数合并为1个,因为在真实的情况下,参数输入会太多,几乎有100个输入,函数签名会变得太大,而且我也不想使用dblink。
非常感谢.

wb1gzix0

wb1gzix01#

没有一行修改就能实现这一点,你必须重新设计你的代码。
一种可能性是在包含日志消息的函数中添加另一个输出参数。然后代码可能如下所示:

DO
$$DECLARE
   result text;
   errmsg text;
BEGIN
   SELECT test1(NULL) INTO result, errmsg;
   IF errmsg IS NOT NULL THEN
      RAISE EXCEPTION '%', errmsg;
   END IF;

   SELECT test2(NULL) INTO result, errmsg;
   IF errmsg IS NOT NULL THEN
      RAISE EXCEPTION '%', errmsg;
   END IF;

   SELECT test2(NULL) INTO result, errmsg;
   IF errmsg IS NOT NULL THEN
      RAISE EXCEPTION '%', errmsg;
   END IF;
EXCEPTION
   WHEN raise_exception THEN
      GET STACKED DIAGNOSTICS errmsg := MESSAGE_TEXT;
      PERFORM log_entry(errmsg);
END;$$;

字符串

相关问题