交易控制的奇怪行为



我从的文档中研究了PL/pgSQL中的事务控制

根据文档,它说DO块和Proc的行为相同,所以我写了以下代码来验证(从链接示例克隆(

DO
LANGUAGE plpgsql
$QLambda$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END
$QLambda$;

它的工作原理和魅力一样,直到你关闭pgAdmin的自动提交并得到以下错误

ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function inline_code_block line 11 at COMMIT
SQL state: 2D000

问题:自动提交是如何阻碍DO阻止它应该已经在自己的事务中运行的,还是自动提交迫使它成为一个子事务。。我对PG程序中的事务控制感到困惑。。有人能用工作代码解释一下吗。。

psql中,打开autocommit(默认值(:

create table test1(a int);
DO
LANGUAGE plpgsql
$QLambda$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END
$QLambda$;
select * from test1;
a 
---
0
2
4
6
8
(5 rows)

关闭autocommit后,您可以从这里获得:

自动提交关闭模式的工作方式是为您发出一个隐式BEGIN,就在任何不在事务块中的命令之前,该命令本身不是BEGIN或其他事务控制命令,也不是不能在事务块内执行的命令(如VACUUM(。

所以要明确这一点:

BEGIN;
DO
LANGUAGE plpgsql
$QLambda$
BEGIN
FOR i IN 0..9 LOOP
INSERT INTO test1 (a) VALUES (i);
IF i % 2 = 0 THEN
COMMIT;
ELSE
ROLLBACK;
END IF;
END LOOP;
END
$QLambda$;
ERROR:  invalid transaction termination
CONTEXT:  PL/pgSQL function inline_code_block line 6 at COMMIT

因此,具有嵌套事务的是autocommit关闭情况。

最新更新