22、Camunda 补偿事件、事务子流程、分布式事务一致性

本文详细介绍了Camunda中的补偿事件、事务子流程以及如何保证分布式事务一致性。补偿事件仅在任务成功后触发,事务子流程中取消事件需配中断边界事件。错误事件不会直接触发补偿,需手动处理。补偿任务边界不能添加其他事件。Camunda通过事务子流程和补偿事件实现业务最终一致性,推荐用于复杂事务场景。
摘要由CSDN通过智能技术生成

总结

  1. 补偿事件只有当任务成功执行后才有可能触发;
  2. 事务子流程有取消事件,边界必须要有中断取消事件;
  3. 事务子流程只有触发取消事件,补偿事件才会触发;
  4. 事务子流程边界中断错误事件并不会触发补偿事件;
  5. 报异常的任务非数据库ACID事务时,需额外写逻辑回滚。报异常的任务不会触发补偿事件,当前任务异常技术上会ACID事务回滚。比如当前任务Http Rest操作或文件读写操作,此时补偿事件不会触发,之前创建的文件会一直存在;
  6. 子流程中有补偿事件子流程时,外部补偿结束事件触发子流程中的补偿事件子流程。子流程中没有补偿事件子流程时,外部补偿结束事件会触发子流程中所有任务的补偿事件;
  7. 取消事件 只会在事务子流程中;
  8. 补偿事件任务 后面不能有其他任务;边界不能添加其他事件;
  9. 补偿事件任务 也有可能报异常,不能通过边界错误事件捕获,只能系统报出(流程中断);
  10. 事务子流程中不能添加事件子流程;
  11. Camunda中的分布式事务一致性推荐用事务子流程 完成,业务最终一致性;

补偿事件 Compensation Event

1、按照补偿事件的定义,补偿事件只会在他标识的task成功执行完毕之后才有可能被触发
2、如果他标识的task出现异常,会触发边界异常中断事件,这个补偿事件不会触发(Task出现异常(技术异常),Java事务自动回滚);
3、补偿开启事件只能用于嵌套的事件子流程
Task出现异常,当前Task补偿事件不会触发多个任务补偿事件时,非异常任务的补偿事件会触发异常Task的补偿任务未触发

事务子流程

撤销事件(Cacel Event)表示这个业务事务失败
撤销事件只会出现在事务子流程中
撤销事件有两个形态:
1、当它作为业务事务子流程的终态的时候,表明这个子流程是失败的,需要回滚,继而触发流程中各个任务所定义的补偿处理
2、当它作为业务事务子流程的边界事件的时候,标明这个子流程被回滚了,继而触发外部流程的回滚处理流程,和错误事件一样,撤销事件是中断的,即它会中断外部流程的正常执行路径。
注意:
边界中断取消事件触发时,事务子流程已经被回滚了(事务子流程中的所有补偿事件已经触发执行完成)。边界中断取消事件触发只是为了告诉外部任务,事务子流程已经回滚,如果外部任务需要回滚其他操作时,需要做其他业务操作
在这里插入图片描述

事务子流程中如果有取消事件,必须要有边界取消中断事件

  1. 事务子流程中有取消事件,事务边界必须要有边界取消中断事件,否则执行时找不到边界中断事件报错
  2. 错误边界事件必须要有Code,否则错误边界事件不起作用,有异常捕获不到;
  3. 事务子流程中如果执行了取消事件,整个事务会自动执行对应任务(执行成功过的任务)的补偿事件
    在这里插入图片描述在这里插入图片描述执行出异常的Groovy脚本
println "更新Redis过程中异常"
a=0
b=10/a

事务子流程外部可获取取消事件,外部任务回滚

有时事务子流程数据回滚后,外部已经提交了一些ACID任务时,也需要回滚。
可通过事务子流程边界中断取消事件,添加后续任务,回滚外部任务
如下所示,外部任务回滚后,流程再次流到User Task 保存点(分布式任务回滚到原先保存点),此时流程不会结束,重新修改房源信息再次同步数据(有可能一直死循环回滚)。
在这里插入图片描述

事务子流程边界错误捕获事件,补偿事件不会触发

事务子流程中如果有未知的异常出现,而取消事件未触发;事务子流程边界错误中断事件可捕获到这些异常信息,但是此时不会触发补偿事件,也就是不会触发回滚。需要捕获到事务边界中断错误事件后,做一些业务回滚处理
如下所示,在取消事件 中添加监听器,执行groovy脚本异常:
在这里插入图片描述在这里插入图片描述

补偿任务边界不能添加中间事件

补偿任务边界上不能添加错误捕获事件,如果执行回滚时,也可能出现异常,此时错误时不能捕获到的,这个异常只能Camunda 引擎抛出,流程不能继续执行。
在这里插入图片描述

事务子流程中补偿事件子流程不会触发

**事务子流程中不需要补偿事件子流程,只要范围内出现取消事件,对应所有Task补偿触发在这里插入图片描述在这里插入图片描述

Camunda 如何保证分布式事务一致性

Camunda 并不能操作多个ACID事务回滚,可通过事务子流程 取消事件+补偿事件,完成最终业务事务一致性。
在需要事务的每个Task任务上都需要添加补偿事件

Camunda 分布式事务一致性2种实现

  1. 事务子流程
  2. 补偿事件子流程(错误事件+补偿事件)

错误事件+补偿事件 事件子流程事务一致性?

事件子流程中“错误事件+补偿事件”是否可以完成事务一致性,如果可以为什么还需要有个事务子流程?

  1. 补偿事件子流程同样可以完成事务最终一致性,需要额外判断,实现麻烦;
  2. 事务子流程可简化事件子流程 完成事务一致性,更方便,推荐使用

下面使用 补偿事件子流程 “错误事件+补偿事件”完成事务一致性案例:

错误事件+补偿事件 是否可完成事务一致性?

从下面案例可知,子流程出现异常后触发边界异常中断事件,后面补偿事件子流程 并没有执行。
补偿事件是在任务成功执行完成之后,有可能会触发。这里子流程任务失败了,所以子流程中的补偿事件子流程不会触发。所以以下案例并不能完成事务一致性
在这里插入图片描述在这里插入图片描述

错误事件+补偿事件如何处理可完成事务一致性?

上面案例子流程异常报错,触发边界错误事件,并没有触发补偿事件子流程。如果把子流程的异常内部吃了,不报出来,流程变量记录错误。子流程结束后,通过网关判断是否可完成事务一致性?
修改后的流程如下:
在这里插入图片描述在这里插入图片描述
在这里插入图片描述从下图可知这种补偿事件子流程也可以完成事务一致性操作,只是比事务子流程相对麻烦一些,对于业务事务比较强时,推荐通过事务子流程完成事务一致性。
在这里插入图片描述Script Task 抓取错误异常信息记录流程变量

def id=execution.getProcessInstanceId()
// 是否出现异常信息
def hasError=false
if(execution.hasVariable("vrMsg")){
	def errorMsg = execution.getVariable("vrMsg");
	hasError=true;
	println "流程实例:"+id+",出现异常:"+errorMsg
}
//异常标识设置到变量
execution.setVariable("hasError",hasError)

参考资料

http://www.jiagouc.com/camunda-error-handling-compensation-mechanism-and-distributed-transaction-support/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值