自定义异常
对于存在不可恢复的错误的情况,业务流程管理解决方案将组合使用异常处理程序和自定义异常。
处理异常
可以使用引发由根业务流程处理的异常模式,而不是在调用的业务流程中使用 Terminate 形状。 这样,就可以由对上下文了解最全面的业务流程来决定如何处理异常。 通过让从属业务流程引发自定义异常,使您能够将更具体的信息传递给根业务流程。
业务流程管理解决方案将使用此模式。 解决方案中有四个根业务流程或非所有业务流程: OrderBroker、 OrderManager、 CableOrder1 和 CableOrder2。 三个根业务流程接收并处理自定义异常: OrderManager、 CableOrder1 和 CableOrder2。
请注意,某些根业务流程使用 Terminate 形状,并且 Terminate 形状出现在业务流程的正常终结点之前。 在发生错误时,业务流程仍使用 Terminate 形状,以便业务流程记录为已终止,而不是记录为已完成,但带有错误消息。 这样,解决方案除了可以记录错误之外,还可以轻松跟踪失败的实例。
有关 终止 形状的详细信息,请参阅 如何配置终止形状。 有关 ThrowException 形状的详细信息,请参阅 如何配置引发异常形状。
自定义异常
以下三个自定义异常都使用相同的模式。 使用不同类型是为了便于代码区分不同的异常。
异常 | 引发者(业务流程) |
---|---|
ActivateException | 更改 |
CableOrderException | Activate,CableOrder1 |
InterruptException | CableOrder1、 CheckInterrupt、 ErrorHandlerOrch |
所有自定义异常都在 Utilities 程序集中定义。 自定义异常全部都是 .NET 类。 所有自定义异常类都继承自 .NET ApplicationException 类,后者又继承自 System.Exception 类。 由于异常有可能被冻结(序列化并存储在数据库中),因此异常必须实现反序列化构造函数。 反序列化构造函数是采用两个参数的构造函数:SerializationInfo 对象和 StreamingContext 对象。 在解除异常冻结过程中,将使用反序列化构造函数。 由于 ApplicationException 类已实现反序列化构造函数,因此自定义异常的构造函数仅调用基 (ApplicationException) 反序列化构造函数。 例如, InterruptException 包含以下构造函数:
// "info" is the object holding the serialized object data.
// "context" is the contextual information about the source
// or destination.
public InterruptException(SerializationInfo info,
StreamingContext context) : base(info, context) { }
有关自定义序列化的详细信息,请参阅 .NET Framework 开发人员指南中的“自定义序列化”。
嵌套异常处理程序和补偿模块
除了充当特殊异常之外,一些位置的自定义异常还充当排序标志。 在 更改 业务流程中,必须回滚取消操作的两个位置。
注意
你可能希望在 Visual Studio 中打开 “更改业务流程” 的情况下阅读本部分。
在业务流程的顶部,如果对 Cancel 业务流程的调用失败, CancelCompensation 块将执行并回滚 Cancel 事务。 如果一切顺利,业务流程将调用 Activate 业务流程。
如果 激活 操作失败,还必须回滚 Cancel 事务。 但是,调用 Activate 的异常处理程序对 Cancel 事务一无所知。 为了处理这种情况,提供了一个针对整个业务流程的异常处理程序。 此处理程序包含 Cancel 范围,因此知道 Cancel 事务。 处理程序捕获从 Activate作用域 (ActivateException) 引发的异常,回滚 Cancel 事务,然后再次引发异常,以便调用 更改 业务流程的业务流程可以执行任何其他处理。
请注意,此设计仅在激活失败时补偿取消。 如果 Cancel 失败并引发异常,则 永远不会发生 Cancel ,并且不应进行补偿。
有关补偿块和 补偿 形状的详细信息,请参阅 如何配置补偿形状。