柔性工作流路径变更研究与应用

2021-12-09 06:04李乾仕王淑营曾文驱
计算机与现代化 2021年11期
关键词:会签分支实例

李乾仕,王淑营,曾文驱

(1.西南交通大学信息科学与技术学院,四川 成都 611730;2.广州地铁设计研究院股份有限公司,广东 广州 510010)

0 引 言

近年来,各行业信息逐渐表现出资源异构、分布性、解耦性等特点[1],使用工作流技术来管理业务流程已成为一种趋势[2-4]。工作流是一类能够完全或者部分自动执行的经营过程,根据一系列过程规则、文档、信息或任务能够在不同的执行者之间传递、执行[5],市面上出现了如JBPM(Java Business Process Management)、Activiti、Flowable等具有代表性的工作流产品[6-8]。

企业为了适应越来越激烈的市场竞争和不断变化的业务需求,业务流程随着时间的推移会经常发生改变,当前工作流系统由于工作流程、工作规则的相对固定,很难根据实际变化及时调整流转逻辑、任务权限、任务资源等组成要素。因此,工作流的柔性特性已经成为任何一个工作流推广应用的关键卖点之一,同时也是难点之一[9-10]。

目前,国内外学者们对工作流柔性的理论方法进行了不同角度的研究分析。蒋艳荣等人[11]研究了柔性活动的动态细化方法,通过构建知识树作为启发信息,结合约束进行指导检验,实现柔性活动的动态细化。李金艳等人[12]及马晨华等人[13]从工作流系统柔性访问控制模型着手,分析柔性角色的动态授权。Sprovieri等人[14]研究了一种规划算法来解决业务流程建模灵活性问题,使其可以在运行时计划基于案例的业务流程。通过对各研究的归纳总结,柔性工作流具体表现在以下2个方面:1)任务动态变更,即流程运行期间对任务作出变更后,如任务属性的变更或任务顺序的变更等,无需重启流程,即可实现流程实例的自更新;2)路径动态变更,即在流程建模基础上,任务的执行路径可以根据实际业务情况发生变化,在运行中动态构建静态建模图中没有表示的路径或者动态选择合适的路径。

而对于流程的路径柔性,即在运行过程中实现流程路径的灵活变更成为当前研究的热点方向。有学者[15-16]开发了基于ECA(Event-Condition-Action)规则的图形化工作流建模工具,通过在流程的关键决策点制定响应机制,为用户提供选择“执行路径”的灵活性。为了解决云服务工作流灵活性问题,Fradj等人[17]在构建了BPMN模型的基础上,使用状态图表示云服务工作流行为,控制系统负责根据状态图定义的引擎行为来决定工作流的执行,从而实现路径柔性。

通过分析归纳,上述研究在工作流路径动态选择及变更问题上,对国内的工作流系统而言仍有如下方面亟待改进:1)多数研究只是加入了规则约束且在关键节点处才能响应路径的变化,不适合国内工作流系统任意节点业务路径多变的特性;2)国内工作流系统审批任务众多,面临着多步多分支回退,涉及任务重做,现有研究没有涉及重做过程的数据一致性;3)对于多审批会签的工作流系统,难以实现在流程运行中修改并行路线。上述需求都是工作流柔性问题的重要表现,本文在现有研究及工具基础上对其进行分析改进。

1 柔性工作流路径变更分析

工作流的应用分为2个阶段,建模阶段和运行阶段,流程建模是设计人员对业务过程进行抽象提取,利用建模工具按照工作流建模标准设计出可以通过工作流引擎解析并运行的流程[10]。现有的工作流系统一旦模型建立,除了其中定义的路径判断,很难在运行阶段根据实际需求更改路径及分支,比较典型的问题有流程回退和任务加签,本文对这2个问题进行分析并提出相应的技术解决方案,以此增强工作流的路径柔性。

1.1 流程回退路径变更

图1为传统工作流系统实现回退功能的审批工作流建模图。

图1 传统工作流审批回退流程模型图

图1描述的业务为:用户办理评审任务时,审批人员根据前序任务的办理情况,可以指定驳回到前序任务,从而实现流程的流转控制。从图1中可以看出,驳回的流转线需要体现在模型图上。但是在实际的企业流程模型中,涉及的任务量往往是庞大的。对于需要具备回退功能的任务节点而言,需要流程建模人员在建模阶段考虑大量的与运行时业务相关的操作,偏移了建模人员的关注点。除此之外,企业需求是多变的,建模完成的流程图可能在运行阶段需要更改。传统工作流系统必须更改建模图再重启流程方能生效,即无法在流程运行中变更流转路径。

因此工作流系统需要在运行中实现用户的自定义回退,而不需要所有回退的情况都在建模阶段定义。虽然目前,很多工作流系统应用都对这一业务进行了补充和改进,但是,多数回退仅支持简单的回退,对有并行路由和排他路由的回退研究较少,没有考虑回退中任务数据的一致性并且会发生回退死锁[18-19]。接下来分析流程回退存在的几种场景。

1.1.1 典型回退场景分析

1)顺序、排他分支(XOR)及合并回退。

顺序分支即2个活动之间呈前驱后继关系,节点之间只有一条通路。这种模式回退较简单,不用考虑回退后数据一致性问题与流程死锁,数据恢复也容易实现,直接回退到历史表中的目标节点即可。

排他分支与排他合并的流程模型图如图2所示,排他分支节点后有多条分支,在执行过程中,只能选择其中一条路径,所以此种模式分支与合并的回退与顺序回退方式相同。

图2 包含排他路由的流程模型图

2)并行(AND)分支回退。

流程执行到并行分支会创建多条同步执行的路径,所以在跨并行回退时需要考虑其他分支的执行情况。如图3所示,当活动4需要回退到活动2时,流程运行到AND分支再次同步创建分支任务,由于另一条并行分支的活动7处于正在执行状态,导致其前后数据不一致的问题出现。

图3 并行分支回退

3)并行合并回退。

与图3所描述功能相对应的是并行合并回退,如图4所示。当活动7回退到活动4后,AND合并分支将一直等待活动6的触发,但是活动6并没有创建,导致流程死锁的出现。

图4 并行合并回退

1.1.2 支持跨分支合并的回退算法

为了更好地表达改进的流程回退理论方法,本文通过形式化定义来描述算法中需要的流程相关概念。

一个流程可以用二元组E来定义,其中A表示流程的活动集,R代表活动之间的依赖关系,A和R的定义如下:

A用四元组A(split_type,join_type,AC,status)表示。1)split_type与join_type表示该活动节点类型,其值可为Null、AND(并行)、XOR(排他)。Null代表该活动为顺序线性活动,当split_type为AND,表示活动为并行分支活动,为XOR表示排他分支活动,当join_type为AND代表并行合并活动,为XOR代表排他合并活动。2)AC表示该活动的前驱节点集合。3)status描述该活动实例状态,有未启动、挂起、激活、已完成这4种状态。通过以上信息基本描述了在回退过程中需要的活动信息。

R表示活动之间的依赖集合。可以通过R表示,access表示a到b的可达性,即是否存在至少一条从活动a到b的通路,如果可达,则access为true,否则为false。type表示a到b之间通路类型,根据上文对几种回退场景的分析,总结出如下几种通路类型:顺序关系Sequence,跨并行分支AndSplit,跨并行合并AndJoin,跨排他分支XorSplit,跨排他合并XorJoin。

本文在上述定义描述的基础上,对现有工作流回退逻辑进行改进,研究支持跨并行及合并的多步回退算法。算法1主要表达了在不同分支路由情况下获取可回退节点集合的不同处理逻辑,以保证流程数据的一致性且不会发生死锁等问题。

算法1 获取可回退节点的回溯算法

Input: 活动信息集E,回溯任务currentAct,待回退活动srcAct

Output: 可回退目标节点集rollbackList

1: function GetRollbackList(E,currentAct,srcAct)

2: for i←0 to currentAct.AC.length do

3: preAct←currentAct.AC[i]

//若preAct已经回溯访问过了、currentActc处于激活状态或者与待回退活动不可达,则跳过

4: if preAct is visited or currentAct.status==active or R(preAct,srcAct).access==false then

5: continue

6: end if

7: if R(preAct,currentAct).type==Sequence then

8: add preAct to rollbackList

9: else if R(preAct,currentAct).type==AndSplit then

10: terminate all subsequent activities of preAct

11: add preAct to rollbackList

12: else if R(preAct,currentAct).type==AndJoin then

13: add A(currentAct).AC to rollbackList

14: else add preAct to rollbackList//排他分支合并情况

15: end if

//进入下层回溯

16: GetRollbackList(E,preAct,srcAct)

17: end for

18: return rollbackList

19: end function

1.1.3 回退执行

在解决了回退列表的获取问题后,下一步则是根据用户的选择,执行回退操作。在执行回退时,需要记录2个方面的信息:1)回退前的流程实例上下文信息,用于回退异常恢复现场;2)回退的目标活动历史执行数据,用于回滚历史操作,因为目标活动必然是已完成活动,该部分信息可以通过历史记录表获取,作为目标回退后再次执行该活动的数据来源,保证数据的一致性。图5为执行回退逻辑的流程图。

图5 回退执行流程图

1.2 并行任务分支路径变更

1.2.1 并行会签任务现状

在如办公自动化系统、电子政务系统、企业MIS系统中,都有涉及会签的功能[20-21],即一个任务以并行的方式多人办理,满足一定条件(如通过率)才进入下一任务。图6为截取的一段多专业设计师的会签审批流程图。

图6 传统工作流审批会签流程模型图

从图6可知,当前大多工作流系统实现多专业审批任务会签时,在模型图就构建了并行的多个任务[22]。带来的问题是:首先,随着企业组织人员的扩大,后续也会加入更多的人员审批,需要在模型图上继续增添并行分支路径;其次,这些任务的功能相似,只是办理人员不同。所以这种方案造成流程图模型及功能冗余复杂。

1.2.2 支持运行中并行任务路径变更的解决方案

现有工作流实现并行会签需要在流程建模阶段设置多个并行任务,不符合柔性工作流的需求特征。本文提出如下解决办法,在不改变模型图的基础上,实现运行中并行任务的路径变更。

1)扩展配置文件。

就此问题的解决方案,本文通过研究工作流BPMN模型规范文件[23],对其进行扩展,如图7所示,扩展增加多实例节点的配置信息部分。

图7 实现多实例并行路径变更的扩展配置

图7的内容为关键配置信息,具体解释如下:

assigneeList与assignee从流程变量得到,其来源于建模阶段的任务节点配置,表示会签人员列表和当前会签人员。

isSequential表示多实例任务是串行还是并行,串行则先后创建任务,否则代表并行创建多个同步任务实例。

completionCondition代表该任务完成条件,可直接配置逻辑表达式,如上文中,当通过人数/总实例大于等于0.6则通过,也可配置实现类的全路径,通过注入Bean方式获取。

2)多实例任务的创建。

多实例任务的创建与普通任务创建不一样,多实例任务在流程图上的表现为单节点,存在着一对多的内在逻辑关系,而普通任务节点完全按照流程定义节点数进行分配。为了实现该功能,本文通过增加以下流程变量,如表1所示,将用户设计的可配置文件解析为业务中可以感知的流程状态,从而实现多实例任务创建过程的控制逻辑。

表1 多实例任务创建所需的流程变量

接下来结合以上变量的变化对不同串/并行多实例任务的创建过程进行分析。

1)多实例串行任务的创建。

图8为创建多实例串行任务的逻辑图,除了要创建多个串行子任务以外,还需要创建单独的子流程执行实例。这样做的目的,一是将变量作用域进行细分,二是串行多任务的执行不会影响原有执行实例。流程变量的初始值如表2所示。

图8 多实例串行任务创建示意图

表2 创建多实例串行任务的流程变量初始化

在执行过程中,表2的流程变量需要根据执行情况发生变化,情况如下:每当完成一个任务后,numOfCompletedInstances自加;numOfActiveInstances保持为1,因为一次只有一个串行任务正在执行;loopCounter在此情况下标识历史串行执行数,进行自加操作。

2)多实例并行任务的创建。

与多实例串行任务不同的是,每个并行任务都属于一个新的子级执行实例,它们有着相同的父级执行实例,如图9所示,因为并行任务相互独立,分配在不同的执行实例可达到解耦合、提高容错性的目的。流程变量的初始值如表3所示。

图9 多实例并行任务创建示意图

表3 创建多实例并行任务的流程变量初始化

在执行过程中,每当完成一个任务后,numOfCompletedInstances自加,numOfActiveInstances自减;此时loopCounter标识每一个并行任务,所以保持不变。

通过以上分析,结合图10的业务逻辑处理,则可在不改变流程模型基础上,实现运行中多并行任务的加签功能,同时保证各执行分支的数据隔离性。

图10 实现多实例任务创建的流程图

2 支持路径变更的模型实现及验证

2.1 总体框架

本文结合当前流行的工作流引擎Flowable,在引擎组件中加入路径变更管理器,实现上述逻辑,总体组件框架如图11所示,包括以下几部分:1)事务管理器;2)模型解析组件;3)数据恢复组件;4)总控制器。

图11 组件框架

在工作流系统中,存在调用外部应用的活动节点,对于这部分节点,在进行回退操作时,也需要进行撤销回退,事务管理器用于统一外部数据事务与流程回退事务,保证数据的一致性。模型分析组件用于这2个方面:一是对流程模型解析,以获取不同回退情况下的模型节点;二是通过本文的回溯算法获取流程模型的可回退列表。数据恢复组件用于对中间活动撤销过程中进行数据恢复。总控制器是负责调用各模块实现具体功能的用户接口。

2.2 基于Flowable的实现

Flowable是Activiti的一个分支,作为目前广泛使用的轻量级业务流程引擎,它可以十分灵活地加入任何应用、服务或者构架中。为了实现本文研究的回退理论及并行多实例会签,对其进行如下的改进实现:

1)在其核心类TaskService中新增stopBeforeRollBack(srcTask,transaction)方法,实现停止当前活动以及其他并行分支的活动,参数1为待回退的活动,参数2为统一回退事务的上下文对象。

2)在processService类中新增方法revokeActsByRollBack(srcTask,destTask,transaction),用于撤销待回退活动与目标活动之间的活动,即删除回退中已执行的活动实例及回滚工作流与业务操作,需要保证回滚处于同一事务当中。

3)新增流程回退核心控制类TaskRollBack,相当于上文回退模型图中的回退控制调度器,主要包括getRollBackList、executRollBack等方法。getRollBackList是对1.1.2节获取可回退活动列表的实现,executRollBack是对1.1.3节所述流程图的功能实现,即调用改进步骤1与步骤2所述的新增方法,执行流程回退。

4)在MultipleTaskService类中增加方法mutipleTaskCreat(bpmnXmlDoc,srcTask),其业务逻辑实现了图10所述的不同情况多实例任务创建,参数1为流程模版XML文件配置信息,参数2代表多实例节点的源任务。

2.3 实例验证

本文所述方法在中车产品快速配置设计平台得以应用,轨道交通设计过程面临着多路由、多分支的审批回退业务,通过引入Flowable引擎,并结合上文所述改进,实现了其设计过程的回退方案和运行中并行会签任务的创建。下面以地铁转向架配置设计流程为例,如图12所示,验证本文所述回退算法的应用效果。

图12 地铁转向架设计工作流模型图

该流程存在顺序、排他、并行多种路由方式,工作流引擎首先加载解析流程模型图,并由引擎控制驱动,当需要执行回退操作时,得到表4所示的可回退目标集合。用户根据设计业务的实际情况,选择具体的回退活动,执行回退操作。值得注意的是,由于活动众多,本文只列举该过程关键回退活动。

表4 测试获取的关键活动可回退结果

在回退集合获取的回溯过程中,由于排他路由的选择,可能会出现回退到从未办理过的活动,所以表中存在多种情况的回退路径。但是,通过本文所述的模型分析组件,在运行中可以发现无效路径,从而选择正确的回退路径。同时,并行分支活动及中间活动的数据与状态在事务管理器与数据恢复组件的作用下也一起回退,实现了回退数据的一致性,体现出优秀的性能。

3 结束语

为了满足工作流系统对实际场景中不确定性的业务变更支持,本文研究了流程路径回退与多实例会签任务加签功能来增强工作流路径变更柔性。文献[18]通过配置条件路径、缺省路径和默认回退路径实现运行中路径选择策略,但是在回退过程没有考虑数据的一致性问题,配置条件不够灵活;文献[22]提出了适应顺序会签和并行会签这2种会签策略,侧重于会签活动通过的规则判断,没有考虑运行中串/并行会签路径的创建问题。本文在现有研究的基础上,从工作流管理系统的路径需求出发,结合Flowable工作流引擎,实现了一个能独立于软件平台的,基于Web应用的柔性工作流系统,并在中车轨道交通产品快速配置设计系统中应用,通过系统的实践与测试,验证了技术的可行性与有效性。此外,如何支持在流程运行阶段更改较为复杂的流程定义并与流程实例实时生效而不产生冲突,是下一步的重点研究内容。

猜你喜欢
会签分支实例
浅谈航天型号产品文件的质量会签
巧分支与枝
一类拟齐次多项式中心的极限环分支
工作流技术在信息通信资源申请中的应用研究
让公文会签业务高效、合理
完形填空Ⅱ
完形填空Ⅰ
生成分支q-矩阵的零流出性
硕果累累