【问题标题】:Rolled back but an error persists回滚但错误仍然存​​在
【发布时间】:2013-10-20 10:37:47
【问题描述】:

语义:

我使用 PostGreSql 9.0.3 作为我的 Dbms。实际上,我试图完成分配给我的目标之一,即当我的存储过程中的 IF - Statement 中的某些条件失败时,使用一些预定义的消息引发异常。由于该异常,应该需要回滚流程。

语法:

 For r3 in select itemname,stock from stock s,items it where s.itemno=it.itemno and it.itemno=$2[I].itemno and s.stockpointno=$1.stockpointno loop
    if xStock > r3.stock then
        RAISE EXCEPTION '%', r3.itemname || ' decreased down from the low stock level'; 
    end if;                           
 End Loop;

其中r3 是记录,xStock 是双精度变量。

然后在存储过程结束时,我只包含以下代码以滚动 回溯交易发生。

Exception when raise_exception then rollback transaction;

我面临的问题是,一旦出现手动异常,就会出现以下错误。

DA00014:ERROR: XX000: SPI_execute_plan_with_paramlist failed executing query "rollback transaction": SPI_ERROR_TRANSACTION

虽然发生了上述错误,但在我签入表格时并未发生交易。我不知道回滚正在进行时出现此特定错误的确切原因。谁能告诉我在我的代码中可能犯的错误是什么?并提出解决此问题的解决方案。

【问题讨论】:

  • 您不需要显式回滚事务以防出错。事务中任何抛出的异常都会导致回滚。
  • 同样的事情可以通过检查条件和/或触发函数来完成。没有循环,没有游标。
  • @IgorRomanchenko Oh.. 那么,在什么情况下我们必须手动使用回滚呢?到目前为止,我错误地认为回滚是由我们手动调用的。
  • @wildplasser 你说的accomplished with a check conditionNo loops, no cursors. 是什么意思?实际上我已经通过在我的代码中使用 if 语句来检查条件。
  • 我不知道xStock 变量从何而来。如果它是来自一个或多个表的表达式,则 OQ 中函数的全部目的似乎是强制执行某些约束(或者它是业务逻辑?)。 2) ROLLBACK 回滚您在当前事务中所做的更改。它还会关闭所有游标。您的会话实质上已重置为其初始状态。所以循环中的光标不再有效。

标签: sql postgresql exception-handling rollback database


【解决方案1】:

虽然一些数据库引擎允许在函数或过程中使用 COMMITROLLBACK,但 PostgreSQL 不允许。任何这样做的尝试都会导致错误:

错误:无法在 PL/pgSQL 中开始/结束事务

这包括异常块内的代码。

另一方面,单独的RAISE EXCEPTION 将使用函数提供的错误消息中止事务,因此无需捕获您自己的异常。如果您刚刚删除了异常块,它将按预期工作。

正如Trapping Errors 中的plpgsql 文档所述:

默认情况下,PL/pgSQL 函数中发生的任何错误都会中止 函数的执行,实际上是周围事务的执行 还有

您当前的代码引发异常,然后捕获它并在异常块中失败,因为禁止的 ROLLBACK 语句导致 SQL 引擎中止事务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-24
    • 2017-05-16
    • 2017-02-25
    • 1970-01-01
    • 2023-01-10
    • 1970-01-01
    • 1970-01-01
    • 2014-08-03
    相关资源
    最近更新 更多