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

时间:2015-12-10 15:32:16

标签: java workflow activiti bpm bpmn

我有一个针对某些业务流程的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) {...}
}

此方法的问题在于业务逻辑代码将随着流程的更新而增长。这会在生产过程中造成很多错误。

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

2 个答案:

答案 0 :(得分:5)

您所描述的是长期运行的任何流程实施的关键难点之一。我实施的许多流程都超过12个月,因此您必须始终考虑流程模型的演变。

Philippe提出了一些降低风险的好方法,但即使将业务逻辑与集成分离并将决策点外部化为规则引擎也并不总能让您获得所需的技术。

您是添加任务和更改变量类型的示例是经典案例,如果您不进行分支,我们在“飞行”过程中调用的内容将在新流程模型中失败。

其他经典示例是无法初始化新流程所需的变量,并且无法在飞行过程中添加决策逻辑。

一般来说,有几种方法可以处理流程演变:

  1. 让旧流程完成原始流程并在新流程上启动新流程。显然这只适用于某些情况,但却是最简单的方法。很长时间的运行过程往往不会落入这个桶中。

  2. 将所有数据外部化到外部记录系统,并最小化进程内部保存的数据(保留引用,而不是数据本身)。这是Phillipe所做的扩展。遵循此最佳实践意味着您的流程逻辑不会与数据紧密绑定,而是仅限于影响流程流程的决策。外部化要求做出这些决策的规则,决策和服务,您可以更自由地修改流程逻辑,同时减少对飞行中流程的影响。

  3. 将业务逻辑添加到流程中以专门处理飞行中。这是您在问题中引用的方法。它是可行的,但正如你所说,它可能成为维护的噩梦。

  4. 通过使用具有良好定义的接口的被调用子流程,在流程中定义“安全区域”或里程碑。这样,您可以以受控方式更改流程的各个部分。显然,在要替换的段内具有令牌的实例会发生什么?如果要部署该段的新模块,您需要随着时间推移出这些实例或提前计划并停止进程进入子流程。

  5. 然后有上述所有组合(这是现实生活中容易发生的事情)。

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

答案 1 :(得分:4)

我遇到了同样的问题,不幸的是,我认为你的问题没有一个简单的答案。不过,我设法通过遵循一些原则来保持对我的代码库的一些理智:

  1. 认识到流程定义和业务逻辑具有不同的开发生命周期。有时他们会去,但通常不会,特别是为了解决新情况(新角色,新批准步骤等)而不断发展的过程

  2. 将“流程逻辑”保持在最低限度。使用脚本语言实现它(我的选择是Groovy,你可以选择任何其他基于jvm的脚本语言)。这样您就可以使用您的流程进行部署,而不必担心不同的版本。

  3. 当进程需要调用业务服务时,请使用REST或SOAP服务等技术来完成。 ESB可以成为您的BPM服务器的便捷伴侣,在您的流程和业务服务之间创建明确的分离。

  4. 希望这些原则可以帮助您思考问题。