错误处理策略

错误处理

错误处理策略

有两种处理流程中的错误和异常的基本策略。使用哪种策略的决定取决于:

1、技术错误与业务错误:该错误是否具有一定的业务意义并导致替代流程(例如“物品无库存”)还是技术故障(例如“当前网络故障”)?

2、显式错误处理或通用方法:在某些情况下,您想要显式地建模在发生错误的情况下应该发生的情况(通常是业务错误)。在很多情况下,您不想这样做,但是有一些适用于错误的通用机制,可以简化流程模型(对于技术错误,通常是这样,想像您必须对每项任务都可能发生网络中断建模吗?您将无法再识别您的业务流程)。

在流程引擎的上下文中,错误通常会作为您必须处理的Java异常而引发。让我们看一下如何处理它们。

交易回滚

标准的处理策略是将异常抛出给客户端,这意味着将回滚当前事务。这意味着过程状态将回滚到最后一个等待状态。用户指南的“ 处理中的事务”部分详细描述了此行为。错误处理由引擎委托给客户端。

让我们在一个具体示例中进行演示:用户在前端收到一个错误对话框,指出由于网络错误当前无法访问库存管理软件。要执行重试,用户可能必须再次单击相同的按钮。即使通常不希望这样做,它仍然是适用于许多情况的简单策略。

异步和失败的作业

如果您不希望向用户显示异常,则一种选择是进行服务调用,这可能会导致错误,异步(如Processes中的Transactions中所述)。在这种情况下,异常将存储在流程引擎数据库中,并且后台的Job被标记为失败(更准确地说,将存储异常并减少某些重试计数器)。

在上面的示例中,这意味着用户将不会看到错误,而会看到“一切成功”对话框。异常存储在作业中。现在,一个聪明的重试策略将在以后自动重新触发作业(当网络再次可用时),或者操作员需要查看错误并触发其他重试。稍后将更详细地显示。

该策略非常强大,并且经常应用于现实生活中的项目中,但是,它仍然将错误隐藏在BPMN图中,因此对于希望在流程图中可见的业务错误,最好使用Error Events

捕获异常并使用基于数据的XOR网关

如果调用可能引发异常的Java代码,则可以在Java委托,CDI Bean或任何其他形式中捕获异常。记录一些信息并继续操作可能已经足够,这意味着您可以忽略该错误。通常,您将结果写入过程变量,然后在过程流中稍后对XOR-Gateway进行建模,以在发生错误时采取不同的路径。

在那种情况下,您可以在流程模型中显式地对错误处理进行建模,但是可以使它看起来像是正常结果,而不是错误。从业务角度看,这不是错误,而是结果,因此,不应轻易做出决定。经验法则是可以用这种方式处理结果,而异常错误则不能。但是,BPMN观点并不总是必须与技术实现相匹配。

例:

我们触发“检查数据完整性”任务。Java服务可能会抛出“ DataIncompleteException”。但是,如果我们检查完整性,则不完整的数据不是例外,而是预期的结果,因此我们更喜欢在流程中使用XOR网关来评估流程变量,例如“#{dataComplete == false}” 。

BPMN 2.0错误事件

BPMN 2.0错误事件使您可以显式建模错误,从而解决业务错误的用例。最突出的例子是“中间捕获错误事件”,它可以附加到活动的边界。定义边界错误事件在嵌入式子流程,调用活动或服务任务上最有意义。错误将导致触发替代处理流程:

查看错误事件中的部分BPMN 2.0实现参考从代表团代码引发错误的部分用户手册以获取更多信息。

BPMN 2.0补偿和业务交易

BPMN 2.0事务和补偿允许您对业务事务边界建模(但是,不能以技术ACID方式),并确保在回滚期间已执行的动作得到补偿。补偿是指使行为的效果不可见,例如,如果您先前已预订了货物,则在货物中进行预订。有关详细信息,请参见BPMN 2.0实施参考BPMN补偿事件BPMN事务子流程部分。

监控和恢复策略

万一发生错误,可以应用不同的恢复策略。

让用户重试

如上所述,最简单的错误处理策略是将异常引发给客户端,这意味着用户必须自己重试该操作。他的操作方式取决于用户,通常是重新加载页面或再次单击。

重试失败的作业

如果使用Jobs(async),则可以利用Cockpit作为监视工具来处理失败的作业,在这种情况下,最终用户不会看到该异常。然后,当重试用尽时,通常会在座舱中看到故障(有关更多信息,请参见Web应用程序的“ 失败的作业”部分)。

在驾驶舱失败作业的部分Web应用程序的更多细节。

如果您不想使用Cockpit,也可以自己通过API查找失败的作业:

List<Job> failedJobs = processEngine.getManagementService().createJobQuery().withException().list();for (Job failedJob : failedJobs) {

  processEngine.getManagementService().setJobRetries(failedJob.getId(), 1);}

显式建模

当然,您总是可以明确地对重试机制建模,如BPMN 2.0中的重试在哪里指出的那样:

我们建议将其限制为您有充分理由希望在流程图中看到它的情况。我们更喜欢异步继续,因为它不会使流程图膨胀,并且基本上可以用更少的运行时开销执行相同的操作,因为“遍历”模型化循环涉及其他操作,例如,编写审核日志。

用户操作任务

我们经常在项目中看到这样的东西:

实际上,这是一种有效的方法,在该方法中,您将错误分配给操作员作为“用户任务”,并对操作员解决问题所需的选项进行建模。但是,这是一个奇怪的混合:我们想处理一个技术错误,但是将其添加到我们的业务流程模型中。我们在哪里停下来?现在我们是否必须对每个服务任务进行建模?

对于这种情况,使用失败的工作列表而不是使用“正常”任务列表感觉更自然,这就是为什么我们通常建议其他可能性,而不将其视为最佳实践。

 技术支持:盘古BPM工作流平台

相关教程