如何回滚PostgreSQL中错误的交易? 我正在为PostgreSQL编写一个脚本,并且由于我希望它被原子执行,因此我将其包装在交易中。 我希望脚本看起来像这样: 开始 - 1)执行一些...

问题描述 投票:0回答:1
,但是,在这种情况下,PGADMIN警告我有关初始

BEGIN
之后的语法错误。如果我通过像这样的分号添加命令终止命令:

BEGIN;
它会告诉我近乎错误的错误。
我意识到,也许我正在混合控制结构和交易的语法,但是我找不到任何关于如何在文档中退缩的交易(也不是这样)。
i还认为,也许交易会自动回滚,但似乎并非如此,因为以下脚本:

EXCEPTION
使我感到震惊:
BEGIN; -- 1) Execute some valid actions; -- 2) Execute some action that causes an error. COMMIT;
我必须手动手动
ERROR: current transaction is aborted, commands ignored until end of transaction block
交易。

似乎我在这里缺少一些基本的东西,但是什么?

Edit:

我也尝试使用

ROLLBACK;

,也喜欢:
DO

Pgadmin用A击中了我:

DO $$ BEGIN -- 1) Execute some valid actions; -- 2) Execute some action that causes an error. EXCEPTION WHEN OTHERS THEN ROLLBACK; END; $$

,这使我无止境,因为那正是我(我认为)在做的事情。 post-peccept编辑:

关于劳伦兹的评论:“您的SQL脚本将包含一个提交。这结束了交易并将其退回。” - 这是我观察到的行为。请考虑以下示例(这只是我原始问题中已经提供的示例的具体版本): ERROR: cannot begin/end transactions in PL/pgSQL. HINT: Use a BEGIN block with an EXCEPTION clause instead.

当我执行上面的脚本时,我会受到:
BEGIN; -- Just a simple, self-referencing table. CREATE TABLE "Dummy" ( "Id" INT GENERATED ALWAYS AS IDENTITY, "ParentId" INT NULL, CONSTRAINT "PK_Dummy" PRIMARY KEY ("Id"), CONSTRAINT "FK_Dummy_Dummy" FOREIGN KEY ("ParentId") REFERENCES "Dummy" ("Id") ); -- Foreign key violation terminates the transaction. INSERT INTO "Dummy" ("ParentId") VALUES (99); COMMIT;

是预期的。 但是,如果我尝试检查我的
ERROR: insert or update on table "Dummy" violates foreign key constraint "FK_Dummy_Dummy". DETAIL: Key (ParentId)=(99) is not present in table "Dummy".
表是被创建还是回滚,则是这样的:

Dummy

启用一个简单的

SELECT EXISTS ( SELECT FROM information_schema."tables" WHERE "table_name" = 'Dummy'); ,我得到的错误与已经提到两次的错误:false。然后,我必须通过发行ERROR: current transaction is aborted, commands ignored until end of transaction block对我来说,似乎上面提到的评论是错误的,或者至少我在这里误解了某些内容。

除了在某些有限的情况下,您不能在PL/PGSQL中使用
ROLLBACK;

您无需明确的卷回去您的PL/PGSQL代码。只需让异常从PL/PGSQL代码传播,它将导致错误,这将导致整个事务回滚。
您的评论表明,此代码是从SQL脚本调用的。然后,解决方案是在PL/PGSQL代码之后的某个位置将其在该SQL脚本中放置一个。那将结束交易并将其滚回去。
    
当我试图在脚本提出例外之后尝试运行脚本时,我也有这个错误:

error:当前事务被中止,命令被忽略到交易块结束之前

要修复它,我只是在脚本的开头添加了“回滚”,例如:

ROLLBACK
    
我认为您必须使用较旧的版本,因为问题的确切代码对我而言而没有错误:

postgresql exception transactions plpgsql rollback
1个回答
18
投票

这对我来说也很好,没有例外:

为每次注释

,您可以删除函数中的异常块,如果发生错误,则其中的事务运行将自动回滚。从我有限的测试中,情况似乎就是这种情况。


© www.soinside.com 2019 - 2025. All rights reserved.