我有一个用于某些业务流程的Activiti项目。

问题在于迁移。现有流程有一些未完成的任务。我想通过添加新步骤来修改现有流程。

现在,当我创建一个新任务时,将根据更新的过程来处理此新任务。未完成的任务将按照旧过程进行处理。

让我们以下面的示例为例:https://spring.io/blog/2015/03/08/getting-started-with-activiti-and-spring-boot

在此示例中,请考虑以下行:

taskVariables.put("telephoneInterviewOutcome", true);

假设,我有一些业务逻辑代码在其中检查该变量的值,例如:
if (taskVariables.get("telephoneInterviewOutcome") == true) {...}

现在假设,我想将此变量从Boolean修改为Enum。现在,我还需要更新我的业务逻辑:
if (taskVariables.get("telephoneInterviewOutcome") == SOMEENUM) {...}

现在,需要根据手头任务的处理版本来分支我的业务逻辑代码。如果任务属于流程的版本1,则我将使用第一个语句,否则将使用第二个语句:
if (getProcessVersion(task) == 1) {
    if (taskVariables.get("telephoneInterviewOutcome") == true) {...}
} else {
    if (taskVariables.get("telephoneInterviewOutcome") == SOMEENUM) {...}
}

这种方法的问题在于,业务逻辑代码将随着流程的更新而增长。这将在生产过程中导致许多错误。

还有其他解决方案吗?如何在不更改业务逻辑代码的情况下解决此问题?

最佳答案

您所描述的是任何长期运行的流程实现的主要痛点之一。我实现的许多流程的使用时间都超过了12个月,因此您始终必须考虑流程模型的演变。

Philippe提出了一些降低风险的好的技术,但是即使将业务逻辑与集成分离并将决策点外部化到规则引擎,也不一定能使您始终如一。

您以添加任务和更改变量类型为例,这是经典情况,如果您不分支,我们所谓的“运行中”流程将在新流程模型中完全失败。

其他经典示例包括未能初始化新流程所需的变量,以及添加了决策逻辑,该逻辑对于飞行中的流程永远无法成功。

通常,有几种方法可以处理流程:

  • 让旧进程完成其原始流程,并在新流程上启动新流程。显然,这仅在某些情况下有效,但这是最简单的方法。运行时间非常长的进程往往不会落入这个桶中。
  • 将所有数据外部化到外部记录系统,并最小化流程本身中保存的数据(保留引用,而不是数据本身)。这是Phillipe提出的观点的延伸。遵循此最佳实践意味着您的流程逻辑与数据并没有那么紧密地绑定(bind)在一起,相反,它仅与影响流程流程的决策绑定(bind)在一起。外部化用于制定这些决策的规则,决策和服务,您可以自由地修改流程逻辑,而对运行中的流程影响较小。
  • 将业务逻辑添加到流程中以专门处理飞行中的事件。这是您在问题中引用的方法。这是可行的,但正如您所说,可能成为维护的噩梦。
  • 通过使用具有良好定义的接口(interface)的被调用子流程,在流程中定义“安全区域”或里程碑。这样,您可以以受控方式更改流程的各个部分。显然,对于要替换的段中具有 token 的实例,该怎么办?如果要为该网段部署新模块,则需要随着时间流逝释放这些实例,或者提前计划并阻止进程进入子进程。

  • 然后是以上所有内容的组合(这在现实生活中往往会发生)。

    没有简单的解决方案,尽管某些BPMS系统具有可帮助识别潜在升级问题的工具,但仍然取决于良好的体系结构,计划和测试。

    09-11 17:26