从处理块之外的过程中捕获错误
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(或更高版本)起可用。
我有以下代码(为了说明目的进行了简化)。我在 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(或更高版本)起可用。