前面我们已经了解了串行编排和并行编排,了解了两者的执行逻辑,同时都是建立在这两者正常执行情况下,执行的逻辑。那么如果出现chain执行的一系列流程如果出现了异常,此时就需要进行回滚了。如果出现错误或者成功,我们还需要做一些额外的动作的时候,都需要以此为依据来进行的时候,liteflow又是如何处理和留给我们扩展的口子的呢?因此我们来了解一下rollback、onSuccess方法、onError方法是如何执行的。
一、异常回滚的逻辑处理入口
前面我们已经知道,通过chain获取对应的condition,然后通过condition拿到对应的nodeComponent。因此,在处理的过程中,需要对chain.execute(slotIndex)这个方法调用执行try...catch操作。此时可以看到如果当前chain不为空,则此时会打印错误的信息。方便后续日志排查使用。如果为空,依然会进行日志的打印记录。
接着我们可以看到会对槽的信息进行判断,然后设置异常信息。
完成后,会通过槽来获取执行的步骤,也即executeSteps执行步骤。
Deque<CmpStep> executeSteps = slot.getExecuteSteps(); try { Iterator<CmpStep> cmpStepIterator = executeSteps.descendingIterator(); while(cmpStepIterator.hasNext()) { CmpStep cmpStep = cmpStepIterator.next(); if(cmpStep.getInstance().isRollback()) { Rollbackable rollbackItem = cmpStep.getRefNode(); // 进行回滚 rollbackItem.rollback(slotIndex); } } //如果出现异常,则打印异常 } catch (Exception exception) { LOG.error(exception.getMessage()); } finally { //最终打印回滚步骤 slot.printRollbackStep(); }
这里是回滚的主体逻辑。
二、异常逻辑回滚
因此我们需要着重去了解rollback做了什么事情。也即迭代的rollbackItem.rollback(slotIndex)做了什么事情。
首先会把线程属性赋值给组件对象NodeComponent对象。有了nodeComponent的信息之后,执行回滚操作,此时会执行self.rollback()。在此之前会获取槽,然后创建步骤对象cmpStep,添加tag和实例对象、回滚步骤,然后执行回滚操作。可以看到这个方法在是在NodeComponent中的rollback()方法,此时会调用我们自定义的回滚方法,执行回滚动作,也即我们在继承NodeComponent的时候,除了重写process方法之外,还需要重新rollback方法,来执行我们的回滚逻辑,这段逻辑需要我们在业务系统实现。
public void rollback() throws Exception{ // 如果需要失败后回滚某个方法,请覆盖这个方法 };
完成回滚之后,执行移除,也即removeSlotIndex和removeRefNode。
三、异常回滚之外
当然除此之外,我们还可以实现对应的onSuccess方法、onError方法。可以看到在NodeComponent类中,我们可以看到这两个方法都存在,我们都可以选择性的复写,来保证业务的正常执行之外,异常的补偿或者处理等。
onSuccess方法
public void onSuccess() throws Exception { // 如果需要在成功后回调某一个方法,请覆盖这个方法 // 全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类 // 非spring环境下,全局切面为空实现 CmpAroundAspectHolder.loadCmpAroundAspect().onSuccess(this.self); }
onError方法
public void onError(Exception e) throws Exception { // 如果需要在抛错后回调某一段逻辑,请覆盖这个方法 // 全局切面只在spring体系下生效,这里用了spi机制取到相应环境下的实现类 // 非spring环境下,全局切面为空实现 CmpAroundAspectHolder.loadCmpAroundAspect().onError(this.self, e); }
我们可以对其进行复写,来实现自己的逻辑。
除此之外,还有一些其他的方法,比如:isContinueOnError出错是否继续执行、isAccess是否进入该节点、是否结束整个流程(不往下继续执行)。
这些都是liteflow提供给我们的。
参考:https://gitee.com/dromara/liteFlow