错误和条件执行
适用于:Azure 数据工厂 Azure Synapse Analytics
条件路径
Azure 数据工厂和 Synapse Pipeline 业务流程支持条件逻辑,并且使用户能够根据先前活动的结果采取不同的路径。 使用不同的路径允许用户构建可靠管道并在 ETL/ELT 逻辑中合并错误处理。 总共允许四个条件路径,
名称 | 说明 |
---|---|
成功时 | (默认通行证)如果当前活动成功,则执行此路径 |
失败时 | 如果当前活动失败,则执行此路径 |
完成时 | 在当前活动完成后执行此路径,无论该活动是否成功 |
跳过时 | 如果活动本身没有运行,则执行此路径 |
可以在一个活动之后添加多个分支,但有一个例外:完成时路径不能与成功时或失败时路径共存。 对于每个管道运行,最多会激活一条路径,具体取决于活动的执行结果。
错误处理
常见错误处理机制
Try Catch 块
在这种方法中,客户定义业务逻辑,并且仅定义“失败时”路径以捕获先前活动中的任何错误。 如果“失败时”路径成功,此方法显示管道成功。
Do If Else 块
在这种方法中,客户定义业务逻辑,并定义“失败时”和“成功时”路径 。 即使“失败时”路径成功,此方法仍显示管道失败。
Do If Skip Else 块
在这种方法中,客户定义业务逻辑,并定义“失败时”和“成功时”路径,同时附加虚设的“跳过时”活动 。 如果“失败时”路径成功,此方法显示管道成功。
摘要表
方法 | 定义 | 活动成功时会显示整体管道 | 活动失败时会显示整体管道 |
---|---|---|---|
Try-Catch | 仅“失败时”路径 | 成功 | 成功 |
Do-If-Else | “失败时”路径 +“成功时”路径 | Success | 失败 |
Do-If-Skip-Else | “失败时”路径 +“成功时”路径(末尾有一个“虚设的跳过时”) | 成功 | 成功 |
如何确定管道故障
不同的错误处理机制会导致管道处于不同的状态:部分管道失败,部分管道成功。 我们如下所示确定管道成功和失败:
- 评估所有叶节点活动的结果。 如果跳过叶节点活动,我们会评估其父节点活动
- 当且仅当评估的所有节点都成功时,管道结果为成功
假设“失败时”活动和“虚设的失败时”活动成功,
在 Try-Catch 方法中,
- 先前的活动成功时:“失败时”节点被跳过,其父节点成功;整体管道成功
- 先前的活动失败时:“失败时”节点生效;整体管道成功
在 Do-If-Else 方法中,
- 先前的活动成功时:“成功时”节点成功,“失败时”节点被跳过(其父节点成功);整体管道成功
- 先前的活动失败时:“成功时”节点被跳过,其父节点失败;整体管道失败
在 Do-If-Skip-Else 方法中,
- 先前的活动成功时:“虚设的跳过时”节点被跳过,其“成功时”节点成功;其他节点活动,“失败时”节点被跳过,其父节点成功;整体管道成功
- 先前的活动失败时:“失败时”节点成功,“虚设的跳过时”节点成功;整体管道成功
条件执行
随着我们开发更加复杂和复原能力更强的管道,有时需要向逻辑引入条件执行,即仅在满足特定条件时执行特定活动。 这方面的用例很多,例如:
- 执行后续活动,例如发送电子邮件通知(如果以前的复制作业已成功)
- 如果前面的任何活动失败,则运行错误处理作业
- 如果活动本身或其相应的错误处理活动成功,则继续执行下一步
- 等等
下面将介绍一些常见逻辑以及如何在 ADF 中实现它们。
单个活动
以下是单个活动之后的一些常见模式。 我们可以使用这些模式作为构建基块来构造复杂的工作流。
错误处理。
模式是 ADF 中最常见的条件逻辑。 错误处理活动是为“失败时”路径定义的,如果主活动失败,将调用该活动。 对于需要回退替代项或记录的所有任务关键步骤,应将其合并为最佳做法。
尽力而为的步骤
某些步骤(如信息性记录)不太重要,因此其故障不应阻止整个管道。 在这种情况下,我们应该采取尽力而为的策略:将后续步骤添加到“完成后”路径,以解除工作流的阻碍。
且
第一种,也是最常见的方案是有条件的“与”:当并且仅当前面的活动成功时,才继续执行管道。 例如,你可能具有多个复制活动,在进入下一个数据处理阶段之前,需要先成功完成这些活动。 在 ADF 中,可以轻松实现该行为:为下一步声明多个依赖项。 从图形上看,这意味着指向下一个活动的多行。 可以选择“成功后”路径以确保依赖项已成功,也可以选择“完成后”路径,以允许尽力执行。
在此处,仅当两个 Web 活动都成功执行后,才会执行后续等待活动。
在这里,当 ActivitySucceeded 通过和 ActivityFailed 完成时,将执行后续等待活动。 请注意,如果使用“成功后”路径,则 ActivitySucceeded 必须成功,而“完成后”路径上的 ActivityFailed 会尽力运行,也就是说,可能会失败。
或
第二种常见方案是有条件的“或”:如果任何依赖项成功或失败,则运行活动。 此处我们需要使用“完成后”路径、If 条件活动和表达式语言。
在深入了解代码之前,我们还需要了解一件事。 活动运行并完成后,可以使用 @activity('ActivityName').Status 引用其状态。 它可以是“已成功”,也可以是“失败”。 我们使用此属性来生成条件或逻辑。
共享错误处理记录步骤
在某些情况下,如果前面的任何活动失败,可能需要调用共享的错误处理或记录步骤。 可以生成如下所示的管道:
- 并行运行多个活动
- 在 True 分支中添加 if 条件以包含错误处理步骤
- 使用“完成后”路径将活动连接到条件活动
- 条件活动读取的逻辑表达式
@or(equals(activity('ActivityFailed').Status, 'Failed'), equals(activity('ActivitySucceeded').Status, 'Failed'))
- 注意:你需要连接,或者如果具有两个以上的依赖项活动,例如,
@or(or(equals(activity('ActivityFailed').Status, 'Failed'), equals(activity('ActivitySucceeded1').Status, 'Failed')),equals(activity('ActivitySucceeded1').Status, 'Failed'))
如果任何活动已成功,则为 Greenlight
当所有活动都为尽力时,如果之前的任何活动已成功,则可能需要继续执行下一步。 可以生成如下所示的管道:
- 并行运行多个活动
- 在 True 分支中添加 if 条件以包含后续步骤
- 使用“完成后”路径将活动连接到条件活动
- 条件活动读取的逻辑表达式
@or(equals(activity('ActivityFailed').Status, 'Succeeded'), equals(activity('ActivitySucceeded').Status, 'Succeeded'))
- 注意:该图外观与上一个方案完全相同。 唯一的区别在于使用的表达式语言
复杂方案
所有活动都需要成功才能继续
该模式是两者的组合:条件和 + 错误处理。 如果所有活动都已成功,管道将继续执行后续步骤,否则将运行共享错误记录步骤。 可以生成如下所示的管道:
- 并行运行多个活动
- 添加 if 条件。 在 True 分支中添加后续步骤,并在 False 分支中添加错误处理代码
- 使用“完成后”路径将活动连接到条件活动
- 条件活动读取的逻辑表达式
@and(equals(activity('ActivityFailed').Status, 'Succeeded'), equals(activity('ActivitySucceeded').Status, 'Succeeded'))
常见模式
Try-Catch-Proceed
该模式等效于尝试编码中 Try Catch 块。 管道中的活动可能会失败。 如果失败,客户将需要运行错误处理作业来处理它。 但单个活动失败不应阻止管道中的后续活动。 例如,我尝试运行复制作业,以将文件移动到存储中。 但它可能中途失败。 在这种情况下,我想从存储帐户中删除已部分复制的不可靠文件(我的错误处理步骤)。 但我可以在此后进行继续其他活动。
要设置该模式:
- 添加第一个活动
- 向 UponFailure 路径添加错误处理
- 添加第二个活动,但不连接到第一个活动
- 将错误处理活动中的 UponFailure 和 UponSkip 路径连接到第二个活动
注意
每个路径(UponSuccess、UponFailure 和 UponSkip)可以指向任何活动。 多个路径可以指向同一活动。 例如,UponSuccess 和 UponSkip 可以指向一个活动,而 UponFailure 可以指向另一个活动。
错误处理作业仅在第一个活动失败时运行。 无论第一个活动成功与否,都将运行下一个活动。
通用错误处理
通常,我们会在管道中按顺序运行多个活动。 如果发生任何失败,我将需要运行错误处理作业来清除状态和/或记录错误。 例如,我在管道中进行顺序复制活动。 如果其中任何一个失败,我将需要运行脚本作业来记录管道故障。
要设置该模式:
- 生成顺序数据处理管道
- 将通用错误处理步骤添加到管道末尾
- 将上一个活动中的 UponFailure 和 UponSkip 路径连接到错误处理活动
仅当前面的任何活动发生失败时,才会运行最后一步“通用错误处理”才会运行。 如果它们全部成功,则不会运行。
可以添加多个活动进行错误处理。