我可以要求 Postgresql 忽略事务中的错误吗

Posted

技术标签:

【中文标题】我可以要求 Postgresql 忽略事务中的错误吗【英文标题】:Can I ask Postgresql to ignore errors within a transaction 【发布时间】:2011-02-14 01:49:55 【问题描述】:

我使用带有 PostGIS 扩展的 Postgresql 进行临时空间分析。我通常在 psql 中手动构建和发出 SQL 查询。我总是将分析会话包装在事务中,因此如果我发出破坏性查询,我可以将其回滚。

但是,当我发出包含错误的查询时,它会取消交易。任何进一步的查询都会引发以下警告:

错误:当前交易是 中止,命令被忽略,直到结束 交易区块

有没有办法可以关闭这种行为?每次我打错字时都回滚事务并重新运行以前的查询是很烦人的。

【问题讨论】:

【参考方案1】:

(更新:不需要手动执行此操作,我在 postgresql 邮件列表中询问,结果证明此行为已通过 psql 客户端中设置的ON_ERROR_ROLLBACK 实现)

要详细说明 Simon 的答案 (+1) ,在您的场景中,您可以在每个交互式查询之后添加一个保存点,始终使用相同的名称(如果查询成功,它会覆盖前一个)。如果出现错误,您会返回上次保存的内容并从那里继续。

这种工作模式的一个例子:

db=# select * from test_gral ;
 i |  t   |  n
---+------+------
 1 | text | 10.0
(1 row)

db=# begin;
BEGIN
db=#  insert into test_gral values (2,'xx',20); savepoint sp;
INSERT 0 1
SAVEPOINT
db=#  insert into test_gral values (3,'xx',30); savepoint sp;
INSERT 0 1
SAVEPOINT
db=#  insert into test_gralxx values (4,'xx',40); savepoint sp;
ERROR:  relation "test_gralxx" does not exist
LINE 1: insert into test_gralxx values (4,'xx',40);
                    ^
ERROR:  current transaction is aborted, commands ignored until end of transaction block
db=# ROLLBACK TO SAVEPOINT sp;
ROLLBACK
db=#  insert into test_gral values (4,'xx',40); savepoint sp;
INSERT 0 1
SAVEPOINT
db=# commit;
COMMIT
db=# select * from test_gral ;
 i |  t   |  n
---+------+------
 1 | text | 10.0
 2 | xx   |   20
 3 | xx   |   30
 4 | xx   |   40
(4 rows)

【讨论】:

ON_ERROR_ROLLBACK 变量完全符合我的要求 :) ON_ERROR_ROLLBACK 看起来像是 psql 客户端的一个特性,而不是 postgres 本身(所以你不能从数据库应用程序中使用它,只能从命令行使用)。 @Glyph:是的,这是 psql 的一个功能,它专门面向交互式使用 - 这是 OP 的场景。对我来说,当期望的行为有意义时,我很难想到一个应用场景。 @leonbloy 好吧,任何其他交互式 SQL 客户端(即支持 postgresql)。【参考方案2】:

关闭它是不可能的,但是你可以使用不同的东西。有类似保存点的东西:

http://www.postgresql.org/docs/8.4/interactive/sql-savepoint.html

这样您就可以将您的事务回滚到某个较早的点,而无需将整个事务变为黑色。

【讨论】:

【参考方案3】:

可以编写一个函数,它接受一个字符串参数 executes 它,并使用 exception 子句以不中止您的事务,但是必须为每个语句调用该函数是一个巨大的痛苦你想执行。

【讨论】:

【参考方案4】:

不,没有办法关闭它。错误会为您隐式中止事务,因此您必须回滚并重试。

【讨论】:

我也是这么想的,但不是。看我的回答。【参考方案5】:

简单的答案是运行

my_db=> \set ON_ERROR_ROLLBACK interactive

在交互式会话中。另请参阅其实现者的this blog post。

【讨论】:

以上是关于我可以要求 Postgresql 忽略事务中的错误吗的主要内容,如果未能解决你的问题,请参考以下文章

Postgresql 捕获事务错误和回滚

错误:当前事务被中止,在创建新记录时忽略命令直到事务块结束

将列分组为一行,忽略 postgreSQL 中的空值

PostgreSQL copy协议与事务

如何调试内部错误当前事务被中止,命令被忽略直到事务块结束?

org.postgresql.util.PSQLException:错误:由于事务之间的读/写依赖关系,无法序列化访问