我从的文档中研究了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
关闭情况。