应用 flowable 工作流框架时,为了将业务零碎和工作流服务进行解耦,将工作流服务独立为一个外围模块,不波及业务逻辑的解决。但凡须要业务数据的中央都通过配置化的模式申请业务零碎,具体配置可参考
<serviceTask id="serviceTask1" name="task1" flowable:delegateExpression="${remoteHttpServiceTask}">
<extensionElements> <flowable:field name="requestUrl">
<flowable:string><![CDATA[http://baseweb-service/testXml]]></flowable:string>
</flowable:field>
<flowable:field name="requestBody">
<flowable:string><![CDATA[{"age":"2"}]]></flowable:string>
</flowable:field>
<flowable:field name="requestMethod">
<flowable:string><![CDATA[POST]]></flowable:string>
</flowable:field>
</extensionElements></serviceTask>
通过 serviceTask 的模式自定义相干配置,申请业务零碎,获取对应的数据。这样,工作流服务和业务零碎就齐全解耦了。当然,这里是采纳 http 的模式进行跨服务调用的,也能够通过 redis 订阅、音讯队列等模式进行跨服务申请调用,这样的设计是不是很奇妙呢?然而,马上就面临问题了。。。有时候 serviceTask 申请失败了怎么办?网络不通顺怎么办?业务数据须要进行操作回滚怎么办?比方,某个销假流程中,业务零碎中销假表单的状态为初始化状态,首先工作流服务申请业务零碎更改销假状态为销假中状态,接着工作流服务告知业务零碎执行具体逻辑(此处笔者采纳的是 http 调用),然而业务零碎执行出错了或者呈现了其余的谬误,工作流服务岂不是要申请业务零碎复原销假状态或者更改为异样状态(理论状况可能比这个简单的多),这些属于流程图之外的异样思考范畴了,毕竟太多的 serviceTask 不可能所有的都加上弥补机制,怎么办呢?有人立马会想到弥补机制,减少一个弥补工作不久 ok 了吗?然而我的业务性能被宰割成了泛滥独自的模块(即很多的 serviceTask), 如果每一个服务都须要这样的一个弥补机制,那么我的流程图就会变得很臃肿,临时放弃这种抉择! 最初想了一个方法,对立的将这些须要回滚的数据进行入库操作,后盾线程定时查询数据库实现这些弥补机制。(当然,大家如果有很好的方法,能够留言探讨)
serviceTask 局部代码如下:
@Override
public void execute(DelegateExecution delegateExecution) {log.info(String.format("服务工作开始执行,ExecutionId--->%s", delegateExecution.getId()));
if (Objects.isNull(requestUrl) || Objects.isNull(requestMethod)) {log.error("requestUrl or requestMethod is empty");
return; }
String urlStr = parseExpression(requestUrl, delegateExecution, serviceConfig::processHttpUrl);
String methodStr = parseExpression(requestMethod, delegateExecution, Function.identity());
String jsonStr = parseExpression(requestBody, delegateExecution, Function.identity());
try {switch (methodStr) {
case MethodType.GET:
ResponseEntity<String> getResponseEntity = httpUtil.sendGetMethod(urlStr, jsonStr, String.class);
handleResponse(getResponseEntity, delegateExecution);
break; case MethodType.POST:
ResponseEntity<String> postResponseEntity = httpUtil.sendPostMethod(urlStr, jsonStr);
handleResponse(postResponseEntity, delegateExecution);
break; default:
log.error("request method not support");
}
} catch (BpmnError e) {throw e;} catch (Exception e) {e.printStackTrace();
throwExceptionWhenFail(delegateExecution, Collections.EMPTY_MAP);
}
}
当然,这个只是解决了某些须要回滚或更新业务数据状态的问题,目标是为了使流程在可控范畴之内,然而,http 调用出错呢,业务数据和工作流服务之间忽然网络不通顺,或者呈现了大量丢包超时的景象,间接上图
也就是 serviTask1 执行的时候出错了?serviceTask2 要不要继续执行,默认状况下工作流会在 task1 中抛出 exception,若无任何异样捕捉机制,会默认重试三次,而后办法完结(然而流程不会终止,serviceTask2 不会执行)这个中央就分多种状况了。1. 捕捉异样
1.1 流程图捕捉这个异样。本人定义边界异样捕获事件,捕捉到异样时,流程图走向其余的分之
1.2 代码中捕捉异样。然而捕捉异样后怎么办呢?抛出异样,会走默认重试三次,而后办法完结(然而流程不会终止,serviceTask2 不会执行)的逻辑
不抛出异样,servicetask2 继续执行(serviceTask2 有局部数据依赖 serviceTask1),前面还是会报错,一发不可收拾
最终解决形式:手动终止流程
对,间接迷途知返,捕捉异样不抛出并终止流程,这样 serviceTask2 就不会执行了,同时也不会重试三次了(重试三次也能够通过 flowable 相应配置更改,当然有时候须要这个配置,本文中不心愿它进行重试)然而,终止流程这个办法有很多坑,最起码百度下面没有一个能够讲清楚的,详情通过下一篇文章解说