我有一个针对某些业务流程的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所做的扩展.遵循此最佳实践意味着您的流程逻辑不会与数据紧密绑定,而是仅限于影响流程流程的决策.外化所谓的规则,决策和服务以做出这些决策,您可以更自由地修改流程逻辑,同时减少对飞行中流程的影响.
将业务逻辑添加到流程中以专门处理飞行中.这是您在问题中引用的方法.这是可行的,但正如你所说,可以成为维护的噩梦.
通过使用具有良好定义的接口的被调用子流程,在流程中定义"安全区域"或里程碑.这样,您可以以受控方式更改流程的各个部分.显然,在要替换的段内具有令牌的实例会发生什么?如果要部署此段的新模块,您需要随着时间推移出这些实例或提前计划并停止进程进入子流程.
然后是上述所有的组合(这是现实生活中容易发生的事情).
虽然一些BPMS系统具有帮助识别潜在升级问题的工具,但仍然没有简单的解决方案,但仍然归结为良好的架构,规划和测试.