栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

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

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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

Camunda 补偿事件、事务子流程、分布式事务一致性
  • 总结
  • 补偿事件 Compensation Event
  • 事务子流程
    • 事务子流程中如果有取消事件,必须要有边界取消中断事件
    • 事务子流程外部可获取取消事件,外部任务回滚
    • 事务子流程边界错误捕获事件,补偿事件不会触发
    • 补偿任务边界不能添加中间事件
    • 事务子流程中补偿事件子流程不会触发
  • Camunda 如何保证分布式事务一致性
    • Camunda 分布式事务一致性2种实现
  • 错误事件+补偿事件 事件子流程事务一致性?
    • 错误事件+补偿事件 是否可完成事务一致性?
    • 错误事件+补偿事件如何处理可完成事务一致性?
  • 参考资料

总结
  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、补偿开启事件只能用于嵌套的事件子流程;

事务子流程

撤销事件(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/

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/328773.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号