从处理块之外的过程中捕获错误

Catching errors from procedures outside of processing block

我有以下代码(为了说明目的进行了简化)。我在 proc1、proc2 和 proc3 的不同数据库表中创建记录。我想要实现的是......如果我在任何时候循环访问临时表时遇到错误(即使在我已经创建了一堆数据库记录之后),我想回滚所有内容以便不创建任何记录。如果 proc1、proc2 和 proc3 没有问题,它会捕获错误,但我不知道如何将这些错误传递给主处理块,以便它理解并回滚所有内容。换句话说,消息 ('error @ main trans block') 永远不会弹出,所以已经创建的记录保留在数据库中。事实上,什么都不会回滚。

DO TRANSACTION ON ERROR UNDO, THROW:

    FOR EACH tt1:

        RUN proc1.

        FOR EACH tt2 WHERE tt2.field1 EQ tt1.field1:

            RUN proc2.

            FOR EACH tt3 WHERE tt3.field2 EQ tt2.field2:

                RUN proc3.

            END.

        END.

    END.

    CATCH e AS PROGRESS.Lang.AppERROR:

        MESSAGE 'error @ main trans block'
            VIEW-AS ALERT-BOX INFO BUTTONS OK.

    END CATCH. 

END.

PROCEDURE proc1.
    DO TRANSACTION ON ERROR UNDO, THROW:

        /* creating some DB records */

        CATCH e AS PROGRESS.Lang.ERROR:

            RETURN ERROR 'Proc1 ' + e:getmessage(1). 

        END CATCH. 

    END.

END PROCEDURE.

PROCEDURE proc2.
    DO TRANSACTION ON ERROR UNDO, THROW:

        /* creating some DB records */

        CATCH e AS PROGRESS.Lang.ERROR:

            RETURN ERROR 'Proc2 ' + e:getmessage(1). 

        END CATCH. 

    END.

END PROCEDURE.

PROCEDURE proc3.
    DO TRANSACTION ON ERROR UNDO, THROW:

        /* creating some DB records */

        CATCH e AS PROGRESS.Lang.ERROR:

            RETURN ERROR 'Proc3 ' + e:getmessage(1). 

        END CATCH. 

    END.

END PROCEDURE.

TIA

有几个潜在的问题。

首先,您的临时表 tt1 和 tt2 需要在没有 NO-UNDO 标志的情况下定义。

其次,FOR EACH 块正在使用它们的默认错误处理行为,即 ON ERROR UNDO, NEXT. 因此在 FOR EACH 块内引发的错误将导致当前迭代被撤消,而不是整个事务。

我建议添加

BLOCK-LEVEL ON ERROR UNDO, THROW . 

到程序的顶部。或者至少

ROUTINE-LEVEL ON ERROR UNDO, THROW . 

结合所有 FOR EACH 块上的 ON ERROR UNDO, THROW 选项。

BLOCK-LEVEL 错误处理选项自 OpenEdge 11.3(或更高版本)起可用。