子流程
子流程
形容
- 子流程(Sub-process)是一个蕴含其余节点,网关,事件等等的节点
- 自身就是一个流程,同时是更大流程的一部分.子流程是齐全定义在父流程里的,所以叫做内嵌子流程
子流程的两种次要场景:
- 子流程能够应用继承式建模: 很多建模工具的子流程能够折叠,把子流程的外部细节暗藏,显示一个高级别的端对端的业务流程总览
- 子流程会创立一个新的事件作用域: 子流程运行过程中抛出的事件,能够被子流程边缘定义的边界事件捕捉,就能够创立一个仅限于这个子流程的事件作用范畴
应用子流程的限度:
- 子流程只能蕴含一个空开始事件, 不能应用其余类型的开始事件,子途程必须至多有一个完结节点
程序流不能逾越子流程的边界
图形标记
- 子流程显示为规范的节点(圆角矩形),下体面流程是折叠的,只显示名称和一个加号标记,展现了高级别的流程总览:
- 下体面流程是开展的,子流程的步骤都显示在子流程边界内:
- 应用子流程次要是为了定义对应事件的作用域
示例:
- 考察软件/考察推荐工作须要同步执行,两个工作须要在同时实现,在二线反对解决之前.这里,定时器的作用域(比方节点须要及时实现)是由子流程限度的:
XML内容
子流程定义为subprocess元素.所有节点,网关,事件,等等.是子流程的一部分,都须要放在这个元素里
<subProcess id="subProcess"><startEvent id="subProcessStart" />... other Sub-Process elements ...<endEvent id="subProcessEnd" /> </subProcess>
事件子流程
形容
- 事件子流程是由事件触发的子流程.是BPMN 2.0中的新元素
- 事件子流程能够增加到流程级别或任意子流程级别
- 用于触发事件子流程的事件是应用开始事件配置的,所以事件子流程是不反对空开始事件的
- 事件子流程能够被音讯事件,谬误事件,信号事件,定时器事件,或弥补事件触发.开始事件的订阅在蕴含事件子流程的作用域(流程实例或子流程)创立时就会创立.当作用域销毁也会删除订阅。
事件子流程能够是中断的或非中断的
- 一个中断的子流程会勾销以后作用域内的所有流程
- 非中断事件子流程会创立一个新的同步分支
- 中断事件子流程只会被每个激活状态的宿主触发一次
- 非中断事件子流程能够触发屡次
- 子流程是否是中断的,应用事件子流程的开始事件配置
事件子流程不能有任何进入和外出流程
- 当事件触发一个事件子流程时,输出程序流是没有意义的
- 当事件子流程完结时,无论以后作用域曾经完结(中断事件子流程的状况或为非中断,子流程生成同步分支会完结
事件子流程的限度:
- Activiti只反对中断事件子流程
Activiti只反对应用谬误开始事件或音讯开始事件的事件子流程
图像标记
事件子流程能够显示为边框为虚线的内嵌子流程
XML内容
事件子流程的XML内容与内嵌子流程一样,然而要把triggeredByEvent属性设置为true
<subProcess id="eventSubProcess" triggeredByEvent="true"> ...</subProcess>
实例
应用谬误开始事件触发的事件子流程的实例,事件子流程是放在流程级别的,作用于流程实例
事件子流程的XML:<subProcess id="eventSubProcess" triggeredByEvent="true"> <startEvent id="catchError"> <errorEventDefinition errorRef="error" /> </startEvent> <sequenceFlow id="flow2" sourceRef="catchError" targetRef="taskAfterErrorCatch" /> <userTask id="taskAfterErrorCatch" name="Provide additional data" /></subProcess>
事件子流程也能够增加成内嵌子流程.如果增加为内嵌子流程,其实是边界事件的一种代替计划
示例:
- 上面两个流程图,两种状况内嵌子流程会抛出一个谬误事件,两种状况谬误都会被捕捉并应用一个用户工作解决
绝对于 两种场景都会执行雷同的工作,然而两种建模的形式是不同的:
内嵌子流程是应用与执行作用域宿主雷同的流程执行的:
- 意思是内嵌子流程能够拜访它作用域内的外部变量
- 当应用边界事件时,执行内嵌子流程的流程会删除, 并生成一个流程依据边界事件的程序流继续执行,这意味着内嵌子流程创立的变量不再起作用
当应用事件子流程时,事件是齐全由它增加的子流程解决的.
- 当应用边界事件时,事件由父流程解决
- 上面两个流程图,两种状况内嵌子流程会抛出一个谬误事件,两种状况谬误都会被捕捉并应用一个用户工作解决
这两个不同点能够帮忙决定是应用边界事件(内嵌子流程)还是内嵌事件子流程(事件子流程) 来解决特定的流程建模或者实现问题
事务子流程
形容
- 事务子流程是内嵌子流程, 能够用来把多个流程放到一个事务里
- 事务是一个逻辑单元, 能够把一些独自的节点放在一起, 这样它们就能够一起胜利或一起失败
事务的可能后果有三种:
事务胜利,没有勾销也没有因为问题终结
- 如果事务子流程是胜利的,就会应用外出程序流继续执行
- 如果流程起初抛出了一个弥补事件,胜利的事务可能被弥补
- 和一般内嵌子流程一样,事务可能在胜利后,应用两头弥补事件进行弥补
事务勾销,流程达到勾销完结事件
- 所有流程都会终结和删除,触发弥补的一个独自的流程,会通过勾销边界事件继续执行
- 在弥补实现之后,事务子流程会应用勾销边界事务的外出程序流向下执行
事务被问题完结,抛出一个谬误事件而且没有在事务子流程中捕捉(如果谬误被事务子流程的边界事件处理了,也会这样利用)
- 不会执行弥补
- 事务三种不同的后果:
- BPMN事务与ACID(技术)事务的关系: BPMN事务子流程与技术(ACID)事务不能相互混同,BPMN事务子流程不是技术(ACID)事务畛域的
BPMN事务和技术事务有以下不同点:
ACID事务个别是短期的.BPMN事务可能继续几小时,几天,甚至几个月能力实现:
- 思考事务中蕴含的节点可能有用户工作,个别人员响应的工夫比利用工夫要长
- 在其余状况下,bpmn事务可能要期待产生一些事务事件,例如要依据某种秩序执行
- 这种操作通常要相比更新数据库的一条数据,或把一条信息保留到事务性队列中,耗费更长的工夫来实现
- BPMN事务个别要逾越多个ACID事务,因为不能在整个业务节点的过程中放弃一个技术性的事务
BPMN事务会逾越多个ACID事务,所以会丢失ACID的个性:
- 比方,在上述例子中,假如预订旅店和刷信用卡操作在独自的ACID事务中执行,假如预约旅店节点曾经胜利了
- 当初处于一个两头不稳固状态,因为咱们预约了酒店,然而还没有刷信用卡
- 在一个ACID事务中,要顺次执行不同的操作,也会有一个两头不稳固状态
- 不同的是,这个中间状态对事务的内部是可见的.比方,如果通过内部预约服务进行了预约,其余应用雷同预约服务的局部就能够看到旅店被预约了.这意味着实现业务事务时,咱们齐全失去了隔离属性(放弃隔离性,能够为ACID事务取得更高的并发,是能够齐全管制,两头不稳固状态也只继续很短的工夫)
BPMN业务事务也不能应用通常的形式回滚:
- BPMN事务逾越了多个事务,BPMN事务勾销时一些ACID事务可能曾经提交了.这时不能被回滚
BPMN事务运行工夫很长,不足隔离性和回滚机制都须要被区别对待:
应用弥补执行回滚:
- 如果事务范畴抛出了勾销事件,会影响曾经执行胜利的节点,并应用弥补处理器执行弥补
隔离性的不足通常应用特定畛域的解决办法来解决:
- 在下面的例子中,一个旅店房间可能会展现给第二个客户,在咱们确认第一个客户付费之前.尽管这可能与业务预期不符,预约服务可能抉择容许一些适度的预约
事务会因为危险而中断,服务必须解决这种状况:
- 曾经预约了旅店,然而始终没有付款的状况(因为事务被中断了),这时预约服务须要抉择一个策略,在旅店房间预约超过最大容许工夫后,如果还没有付款,预约就会勾销
- 综上所述,ACID解决的是通常问题:回滚,隔离级别和启发式后果,在实现业务事务时,须要找到特定畛域的解决方案来解决这些问题
BPMN事务目前的限度:
BPMN标准要求流程引擎能依据底层事务的协定处理事件:
- 比方如果底层协定触发了勾销事件,事务就会勾销
ACID事务顶层的一致性和优化并发:
BPMN事务保障一致性:
- 要么所有节点都胜利
- 一些节点胜利,对其余胜利的节点进行弥补
- 无论哪种形式,都会有一致性的后果
- 要探讨一些activiti外部的状况BPMN事务的一致性模型是叠加在流程的一致性模型之上的
Activiti执行流程是事务性的,并发应用了乐观锁.在Activiti中,BPMN谬误,勾销和弥补事件都建设在同样的ACID事务与乐观锁之上:
- 勾销完结事件只能触发它理论达到的弥补
- 如果之前服务工作抛出了未声明的异样
- 弥补处理器的成果无奈提交,如果底层的acid事务的参与者把事务设置成必须回滚.
- 当两个并发流程达到了勾销完结事件
- 可能会触发两次弥补,并因为乐观锁异样失败
- 阐明Activiti中实现BPMN事务时,雷同的规定也作用域一般的流程和子流程
为了保障一致性,重要的是应用一种形式思考实现乐观事务性的执行模型
图形标记
事务子流程显示为内嵌子流程, 应用双线边框
XML内容
事务子流程应用transaction标签
<transaction id="myTransaction" > ...</transaction>
实例
调用流动(子流程)
形容
BPMN 2.0辨别了一般子流程(内嵌子流程)和调用节点:
- 相同点: 当流程到达节点时两者都会调用子流程
不同点:
- 调用节点援用流程定义内部的一个流程
- 子流程会内嵌到原始的流程定义中
- 应用调用节点的次要场景: 须要重用流程定义,这个流程定义须要被很多其余流程定义调用
- 当流程执行到调用节点,会创立一个新分支,是达到调用节点的流程的分支
- 这个分支会用来执行子流程,默认创立并行子流程,就像一个一般的流程
下级流程会期待子流程实现,而后才会持续向下执行
图形标记
调用节点显示与子流程雷同,然而粗边框(无论是折叠和开展的). 依据不同的建模工具,调用节点也能够开展,然而显示为折叠的子流程
XML内容
<callActivity id="callCheckCreditProcess" name="Check credit" calledElement="checkCreditProcess" />
子流程的流程定义是在执行阶段解析的,就是说子流程能够与调用的流程离开部署
传递变量
能够把流程变量传递给子流程,反之亦然: 当它启动的时候, 数据会复制给子流程,并在它完结的时候复制回主流程
<callActivity id="callSubProcess" calledElement="checkCreditProcess" ><extensionElements> <activiti:in source="someVariableInMainProcess" target="nameOfVariableInSubProcess" /> <activiti:out source="someVariableInSubProcss" target="nameOfVariableInMainProcess" /></extensionElements></callActivity>
这里应用Activiti扩大来简化BPMN规范元素调用dataInputAssociation和 dataOutputAssociation, 只在应用BPMN 2.0规范形式申明流程变量无效
也能够应用表达式:
<callActivity id="callSubProcess" calledElement="checkCreditProcess" > <extensionElements> <activiti:in sourceExpression="${x+5}"" target="y" /> <activiti:out source="${y+5}" target="z" /> </extensionElements></callActivity>
z = y + 5 = x + 5 + 5
实例
- 订单解决流程图:先判断客户端信用,查看信用阶段设计成调用节点
流程XML:
<startEvent id="theStart" /><sequenceFlow id="flow1" sourceRef="theStart" targetRef="receiveOrder" /><manualTask id="receiveOrder" name="Receive Order" /><sequenceFlow id="flow2" sourceRef="receiveOrder" targetRef="callCheckCreditProcess" /><callActivity id="callCheckCreditProcess" name="Check credit" calledElement="checkCreditProcess" /><sequenceFlow id="flow3" sourceRef="callCheckCreditProcess" targetRef="prepareAndShipTask" /><userTask id="prepareAndShipTask" name="Prepare and Ship" /><sequenceFlow id="flow4" sourceRef="prepareAndShipTask" targetRef="end" /><endEvent id="end" />
- 子流程: