将 Activiti 任务从旧流程迁移到新流程

8
我有一个Activiti项目用于业务流程。
问题是关于迁移的。现有流程有一些未完成的任务。我想通过添加新步骤来修改现有流程。
现在,当我创建一个新任务时,这个新任务将根据更新后的流程进行处理。而未完成的任务将根据旧流程进行处理。
让我们以以下示例为例:https://spring.io/blog/2015/03/08/getting-started-with-activiti-and-spring-boot 在此示例中,请考虑以下行:
taskVariables.put("telephoneInterviewOutcome", true);

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

现在假设我想把这个变量从布尔类型改成枚举类型。那么,我需要同时更新我的业务逻辑:

if (taskVariables.get("telephoneInterviewOutcome") == SOMEENUM) {...}

现在,我的业务逻辑代码需要根据正在处理的任务流程版本进行分支。如果任务属于流程的第一版,则我将使用第一条语句,否则使用第二条语句:

if (getProcessVersion(task) == 1) {
    if (taskVariables.get("telephoneInterviewOutcome") == true) {...}
} else {
    if (taskVariables.get("telephoneInterviewOutcome") == SOMEENUM) {...}
}

这种方法的问题在于,随着流程的更新,业务逻辑代码会变得越来越庞大。这会导致生产过程中出现很多错误。

有没有其他解决方案可以避免修改业务逻辑代码的情况下解决这个问题呢?

2个回答

8
您所描述的是任何长期运行的流程实现中的关键痛点之一。我实施的许多流程都超过了12个月,因此您始终必须考虑流程模型的演变。
菲利普提出了一些降低风险的好技术,但即使将业务逻辑与集成分离并将决策点外部化到规则引擎中,也不能总是达到预期效果。
您提到添加任务和更改变量类型的示例是经典案例,如果不进行分支,那么“在飞行”流程将在新流程模型中失败。
其他经典示例包括未初始化新流程所需的变量以及添加决策逻辑,该逻辑对于正在进行的流程永远无法成功。
通常有几种处理流程演变的方法:
1. 让旧流程完成其原始流程,并在新流程上启动新流程。显然,这仅适用于某些情况,但是是最简单的方法。非常长时间运行的流程往往不属于此类别。
2. 将所有数据外部化到外部记录系统,并最小化在流程本身中保存的数据(保留引用而不是数据本身)。这是菲利普提出的观点的延伸。遵循这个最佳实践意味着您的流程逻辑与数据的绑定不是那么紧密,而是仅绑定到影响流程的决策。外部化规则、决策和调用这些决策和服务的过程,您可以更自由地修改流程逻辑,对正在进行的流程的影响较小。
3. 将业务逻辑添加到流程中,以专门处理“在飞行”流程。这是您在问题中提到的方法。它是可行的,但正如您所说,可能会成为维护噩梦。
4. 通过使用具有明确定义接口的被调用子过程来定义流程中的“安全区域”或里程碑。这样,您可以以受控的方式更改流程的各个部分。显然,对于要替换的段内具有代币的实例会发生什么?您需要将这些实例逐渐排出,或者提前计划并停止进入子过程的流程,如果此段的新模块即将部署。
然后还有以上所有方法的组合(这通常是现实中发生的情况)。
没有简单的解决方案,尽管一些BPMS系统具有帮助识别潜在升级问题的工具,但仍然归结为良好的架构、规划和测试。

6
我曾经遇到过同样的问题,不幸的是,我认为你的问题没有简单的答案。然而,我通过遵循一些原则成功地保持了我的代码库的稳定性:
  1. 认识到流程定义和业务逻辑具有不同的开发生命周期。有时它们会在一起,但通常不会,特别是当一个流程为了应对新情况(新角色、新审批步骤等)而发展时。

  2. 将"流程逻辑"最小化。使用脚本语言实现它(我选择的是Groovy,但你可以选择任何其他基于jvm的脚本语言)。这样你就可以与你的流程一起部署它,不必担心不同版本。

  3. 当流程需要调用业务服务时,使用像REST或SOAP服务这样的技术。一个ESB可以成为你的BPM服务器的好伴侣,创建一个清晰的流程和业务服务之间的分离。

希望这些原则能帮助你思考你的问题。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接